并查集+贪心 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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值