hdu 4424 并查集

思路:将边从大到小排序,判断向哪边连,能使总和最大。

#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\n",sum[Find(1)]);
    }
    return 0;
}

 

posted @ 2013-08-26 15:22  fangguo  阅读(207)  评论(0编辑  收藏  举报