标签:
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 221 Accepted Submission(s): 91
转一发官方题解:http://bestcoder.hdu.edu.cn/
题意:给一棵树,求任意{两点路径上的最大边权值-最小边权值}的总和。 解法:sigma(maxVal[i]−minVal[i])=sigma(maxVal)−sigma(minVal) ;所以我们分别求所有两点路径上的最大值的和,还有最小值的和。再相减就可以了。求最大值的和的方法用带权并查集,把边按权值从小到大排序,一条边一条边的算,当我们算第i 条边的时候权值为wi ,两点是ui,vi ,前面加入的边权值一定是小于等于当前wi 的,假设与ui 连通的点有a 个,与vi 连通的点有b 个,那么在a 个中选一个,在b 个中选一个,这两个点的路径上最大值一定是wi ,一共有a∗b 个选法,爱情经验值为a∗b∗wi 。 求最小值的和的方法类似。 槽点: 一:这题做数据的时候突然想到的把数据范围设在 unsigned long long 范围内,要爆 long long,这样选手在wa了之后可能心态不好找不到这个槽点,当是锻炼大家的心态和出现wa时的找错能力了,把这放在pretest..很良心的。 二,并查集的时候,用是递归的需要扩栈,一般上10w 的递归都需要,所以看见有几个FST在栈溢出的,好桑心。
12957565 | 2015-02-16 11:18:47 | Accepted | 5176 | 842MS | 6820K | 2033 B | G++ | czy |
1 #include<iostream> 2 #include<cstring> 3 #include<cstdlib> 4 #include<cstdio> 5 #include<algorithm> 6 #include<cmath> 7 #include<queue> 8 #include<map> 9 #include<set> 10 #include<stack> 11 #include<string> 12 13 #define N 150005 14 #define M 10005 15 //#define mod 10000007 16 //#define p 10000007 17 #define mod2 1000000000 18 #define ll long long 19 #define ull unsigned long long 20 #define LL long long 21 #define eps 1e-6 22 //#define inf 2147483647 23 #define maxi(a,b) (a)>(b)? (a) : (b) 24 #define mini(a,b) (a)<(b)? (a) : (b) 25 26 using namespace std; 27 28 int n; 29 int f[N]; 30 ull cou[N]; 31 ull suma,sumi; 32 int cnt; 33 34 typedef struct 35 { 36 int a; 37 int b; 38 ull c; 39 }PP; 40 41 PP p[N]; 42 43 bool cmp(PP x,PP y) 44 { 45 return x.c<y.c; 46 } 47 48 int find(int x) 49 { 50 int fa; 51 if(x!=f[x]) 52 { 53 fa=find(f[x]); 54 f[x]=fa; 55 } 56 return f[x]; 57 } 58 59 void merge(int x,int y) 60 { 61 int a,b; 62 a=find(x); 63 b=find(y); 64 if(a==b) return; 65 f[b]=a; 66 cou[a]=cou[a]+cou[b]; 67 } 68 69 void ini() 70 { 71 suma=sumi=0; 72 int i; 73 for(i=0;i<=n;i++){ 74 f[i]=i; 75 cou[i]=1; 76 } 77 for(i=1;i<n;i++){ 78 scanf("%d%d%I64u",&p[i].a,&p[i].b,&p[i].c); 79 } 80 sort(p+1,p+n,cmp); 81 } 82 83 void solve() 84 { 85 int i; 86 int aa,bb; 87 for(i=1;i<n;i++){ 88 aa=find(p[i].a); 89 bb=find(p[i].b); 90 suma+=cou[aa]*cou[bb]*p[i].c; 91 merge(p[i].a,p[i].b); 92 } 93 for(i=0;i<=n;i++){ 94 f[i]=i; 95 cou[i]=1; 96 } 97 for(i=n-1;i>=1;i--){ 98 aa=find(p[i].a); 99 bb=find(p[i].b); 100 sumi+=cou[aa]*cou[bb]*p[i].c; 101 merge(p[i].a,p[i].b); 102 } 103 } 104 105 void out() 106 { 107 printf("Case #%d: %I64u\n",cnt,suma-sumi); 108 cnt++; 109 } 110 111 int main() 112 { 113 cnt=1; 114 //freopen("data.in","r",stdin); 115 //freopen("data.out","w",stdout); 116 //scanf("%d",&T); 117 //for(int ccnt=1;ccnt<=T;ccnt++) 118 //while(T--) 119 //scanf("%d%d",&n,&m); 120 while(scanf("%d",&n)!=EOF) 121 { 122 ini(); 123 solve(); 124 out(); 125 } 126 return 0; 127 }
Valentine's Day Round hdu 5176 The Experience of Love [好题 带权并查集 unsigned long long]
标签:
原文地址:http://www.cnblogs.com/njczy2010/p/4293905.html