分析:
地图上有若干个城镇,城镇都可以看作点,然后给出哪些城镇之间是直接相连的。要解决的是整幅图的连通性问题。比如两个点,判断它们是否连通,或者整幅图共有几个连通分支,就是被分成多少个互相独立的块。因此这个题实质就是求有几个连通分支;如果是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;
}
原文地址:http://blog.csdn.net/a809146548/article/details/44276273