hdu1232详解 畅通工程

题目链接:hdu1232畅通工程

这一题是并查集的题,关键就是找出根结点的数目,下面附上详细的代码和注释讲解:


(注释中  祖先=根节点)

#include<bits/stdc++.h>
int m,n,pre[1010],rank[1010];//pre数组存关系(pre[a]==b表示a的父亲是b),rank数组存树上有多少节点(rank[i]==j表示根节点为i的树上有j个节点) 
void unit(int a)//初始化函数 
{
	for(int i=1;i<=a;i++)
	pre[i]=i,rank[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(rank[a]>=rank[b])//a比b长,把b接到a树上 
	{
		pre[b]=a;
		rank[a]+=rank[b];
	}
	else//b比a长,把a接到b树上 
	{
		pre[a]=b;
		rank[b]+=rank[a];
	}
}
	 
int main()
{
	int i,j,a,b,c;
	while(scanf("%d%d",&n,&m)!=EOF)
	{
		if(n==0)
		break;
		unit(n); //对n个城镇初始化 
		for(i=0;i<m;i++)
		{
			scanf("%d%d",&a,&b);
			un(a,b);
		}
		int  num=0;
		for(i=1;i<=n;i++)//用一个for循环得到祖先的数目 
		if(pre[i]==i)
		num++;
		printf("%d\n",num-1);//祖先数目-1就是需要修的路的数量 
	}
	
}


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值