並查集+貪心 Conquer a New Region HDU 4118 && ZOJ 3659

據說是區域賽的題,拿到的時候可把我嚇壞了,沒想到是水水的一題

題意:

輸入N表示N個城市,再輸入N-1條路a,b,c,c是這條路的運載能力

計算以一個一個城市開始到各個城市運輸的最大量


輸入

5

1 2 1

2 3 1

2 4 1

4 5 1

則以2或4爲中心,輸出1+1+2+1=5


輸入

5

1 2 1

2 3 1

2 4 1

4 5 1

則以4爲中心,輸出1+1+2=4

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define maxn 200005
using namespace std;
struct xxx
{
    int u,v,w;
}num[maxn];            //存下輸入的路,方便排序
int f[maxn];           //父節點
int level[maxn];       //當前點內包含點的個數
long long sum[maxn];   //當前點的運輸量的和
int find(int i)        //找根節點
{
    if(i==f[i])
        return f[i];
    f[i]=find(f[i]);
    return f[i];
}
int cmp(xxx a,xxx b)
{
    return a.w>b.w;
}
int main()
{
    int n;
    int i,j;
    while(scanf("%d",&n)!=EOF)
    {
        for(int i=0;i<n-1;i++)
            scanf("%d%d%d",&num[i].u,&num[i].v,&num[i].w);
        sort(num,num+n-1,cmp);             //先排序,再處理
        for(int i=1;i<=n;i++)              //初始化
        { 
            sum[i]=0;
            f[i]=i;
            level[i]=1;
        }
        long long ans=0;
        i=0;
        for(i=0;i<n;i++)
        {
            int fr,ed;
            fr=find(num[i].u);
            ed=find(num[i].v);
            if(fr!=ed)
            {
                long long t1,t2;                               //注意開long long,沒開WA了一發
                t1=sum[fr]+(long long )num[i].w*level[ed];    //比較兩種方式較大的一種,選擇合適的中心
                t2=sum[ed]+(long long )num[i].w*level[fr];
                if(t1>t2)
                {
                    f[ed]=fr;
                    level[fr]+=level[ed];
                    sum[fr]=t1;
                    ans=t1;
                }
                else
                {
                    f[fr]=ed;
                    level[ed]+=level[fr];
                    sum[ed]=t2;
                    ans=t2;
                }
            }
        }
        printf("%lld\n",ans);
    }
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章