hdu1233详解 还是畅通工程

这一题是并查集的题,和hdu1232有一些不同。


输入的时候用到了struct结构体,这样两个城镇才会和它们之间的距离紧紧“绑”在一起,不会因为用sort排序后,找不到每个距离所对应的两个城镇。


根据距离把struct结构体从小到大排序(用sort对struct结构体排序的方法),然后用for循环遍历排序后的结构体,如果两个城镇的还未连接,就连接它们,并在总距离中加上这两个城镇的距离;

#include<stdio.h>
#include<algorithm>
using namespace std;
int m,n,pre[1010],ran[1010];
struct edge
{
    int a;
    int b;
    int c;
}s[5110];
int cmp(edge a,edge b)
{
    return a.c<b.c;
}

void unit(int a)
{
    for(int i=1;i<=a;i++)
    pre[i]=i,ran[i]=1;
}
int find(int x)//找祖先函数,find(a)的返回值即是a的祖先 
{
    int t=x;//把x存在t中 
    while(x!=pre[x]) x=pre[x];//通过不断的找父亲操作,最终找到x的祖先 
    if(t!=x)//这个if循环是个优化 ,避免树太长,查找超时。 
    {
        int r=pre[t];//暂存t的父亲 
        pre[t]=x;
        t=r;
    }
    return x; 
}
int un(int a,int b)//连接a,b到一棵树上 
{
    a=find(a);
    b=find(b);
    if(a==b)//a,b的祖先一样,那么就不需要连接了 
    return 0;
    if(ran[a]>=ran[b])//a比b长,把b接到a树上 
    {
        pre[b]=a;
        ran[a]+=ran[b];
    }
    else//b比a长,把a接到b树上 
    {
        pre[a]=b;
        ran[b]+=ran[a];
    }
}
     
int main()
{
    int i,j,a,b,c;
    while(scanf("%d",&n)!=EOF)
    {
        if(n==0)
        break;
        unit(n); //对n个城镇初始化 
        m=n*(n-1)/2;
        for(i=1;i<=m;i++)
        scanf("%d%d%d",&s[i].a,&s[i].b,&s[i].c);
        sort(s+1,s+1+m,cmp);//从小到大排序
        int num=0;
        for(i=1;i<=m;i++)
        if(find(s[i].a)!=find(s[i].b))//判断两个城镇是否已经连接
        {
            num+=s[i].c;//在总距离中加上这两个城镇的距离
            un(s[i].a,s[i].b);//连接两个城镇
        }
        printf("%d\n",num);
    }
    
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值