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;

}

 

你可能感兴趣的:(HDU)