码迷,mamicode.com
首页 > 其他好文 > 详细

HDU ACM 1232 畅通工程->并查集

时间:2015-03-15 13:56:02      阅读:413      评论:0      收藏:0      [点我收藏+]

标签:acm   c++   编程   算法   c   

分析:

地图上有若干个城镇,城镇都可以看作点,然后给出哪些城镇之间是直接相连的。要解决的是整幅图的连通性问题。比如两个点,判断它们是否连通,或者整幅图共有几个连通分支,就是被分成多少个互相独立的块。因此这个题实质就是求有几个连通分支;如果是1个,则整幅图都连起来了;如果是2个,只要再修1条路,在两个分支中各选一个点,连起来,这样所有点就连起来了;3个连通分支,则只需再修两条。。。。。。,这样就可以使用并查集很好的解决了。

#include<iostream>   
using namespace std;

int p[1001];

bool Init(int n)                //一开始指向自己
{
	for(int i=0;i<=n;i++)
		p[i]=i;
	return true;
}

int Find(int x)            //找到根节点
{
	int r,i,j;

	r=x;
	while(r!=p[r]) r=p[r];      //路径压缩准备,找到根节点

	i=x;
	while(i!=p[i])
	{
		j=p[i];
		p[i]=r;
		i=j;
	}
	return i;                 //返回根节点
}

bool Merge(int x,int y)      //返回是否需要合并
{
	int tx,ty;

	tx=Find(x);
	ty=Find(y);

	if(tx==ty) return false;
	p[tx]=ty;
	return true;
}

int main()  
{ 
	int N,M,i,a,b,total;

	while(scanf("%d",&N))
	{
		if(N==0) break;
		scanf("%d",&M);

		total=N-1;         //一开始都没连通,最少需要修N-1条路才能把N个城市连接起来
		Init(N
			);
		for(i=0;i<M;i++)
		{
			scanf("%d%d",&a,&b);

			if(Find(a)!=Find(b))  //如果不连通,就把它连起来,还需修路就减一
			{
				Merge(Find(a),Find(b));
				total--;
			}
<span style="font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: rgb(238, 238, 238);">                              //如果两点已经连通,那么这条路只是在图上增加了一个环,对连通性没有影响,忽略。</span>
		}
		printf("%d\n",total);
	}
    return 0;  
}



HDU ACM 1232 畅通工程->并查集

标签:acm   c++   编程   算法   c   

原文地址:http://blog.csdn.net/a809146548/article/details/44276273

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!