思路:将边从大到小排序,判断向哪边连,能使总和最大。
#include<map> #include<set> #include<cmath> #include<queue> #include<cstdio> #include<vector> #include<string> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> #define Maxn 200010 #define Maxm 200010 #define LL __int64 #define Abs(x) ((x)>0?(x):(-x)) #define lson(x) (x<<1) #define rson(x) (x<<1|1) #define inf 0x7fffffff #define LL __int64 #define Mod 1000000007 using namespace std; struct Edge{ int u,v; LL val; int operator <(const Edge &temp) const { return val>temp.val; } }p[Maxn]; int Set[Maxn]; LL sum[Maxn],num[Maxn]; int Find(int x) { if(x!=Set[x]) Set[x]=Find(Set[x]); return Set[x]; } int main() { int n,i,j; while(scanf("%d",&n)!=EOF) { for(i=0;i<=n;i++) Set[i]=i,num[i]=1; memset(sum,0,sizeof(sum)); for(i=1;i<n;i++) scanf("%d%d%I64d",&p[i].u,&p[i].v,&p[i].val); sort(p+1,p+n); int a,b; for(i=1;i<n;i++){ a=Find(p[i].u),b=Find(p[i].v); LL sum1,sum2; sum1=sum[a]+num[b]*p[i].val; sum2=sum[b]+num[a]*p[i].val; if(sum1>sum2){ Set[b]=a; num[a]+=num[b]; sum[a]+=num[b]*p[i].val; } else{ Set[a]=b; num[b]+=num[a]; sum[b]+=num[a]*p[i].val; } } printf("%I64d ",sum[Find(1)]); } return 0; }