zoj 3659
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3659
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<vector> 5 #include<algorithm> 6 using namespace std; 7 8 const int maxn = 200005; 9 int p[maxn],num[maxn]; 10 long long int sum[maxn]; 11 struct Edge{ 12 int u,v,c; 13 bool operator <(const Edge & rh) const{ 14 return c > rh.c; 15 } 16 }; 17 vector<Edge> e; 18 int n; 19 20 int find(int x){ 21 return x == p[x] ? x : p[x] = find(p[x]); 22 } 23 void init(){ 24 e.clear(); 25 memset(sum,0,sizeof(sum)); 26 for(int i=1;i<=n;i++){ 27 p[i] = i; 28 num[i] = 1; 29 } 30 } 31 int main() 32 { 33 //if(freopen("input.txt","r",stdin)== NULL) {printf("Error\n"); exit(0);} 34 35 while(cin>>n){ 36 init(); 37 for(int i=1;i<n;i++){ 38 int u,v,c; 39 scanf("%d%d%d",&u,&v,&c); 40 e.push_back((Edge){u,v,c}); 41 } 42 sort(e.begin(),e.end()); 43 for(int i=0;i<n-1;i++){ 44 int a = find(e[i].u), b = find(e[i].v); 45 long long int suma,sumb; 46 suma = sum[a] + (long long)num[b]*e[i].c ; 47 sumb = sum[b] + (long long)num[a]*e[i].c ; 48 if(suma >= sumb) {p[b] = a; sum[a] = suma; num[a] = num[a] + num[b];} 49 else {p[a] = b; sum[b] = sumb; num[b] = num[a] + num[b];} 50 //printf("%d %d %d %d\n",a,b,suma,sumb); 51 } 52 printf("%lld\n",sum[find(1)]); 53 } 54 } 55 //wa的原因就在于long long没使用正确; 56 //本题巧妙的用并查集,归纳递推;