HDU-1232 畅通工程
不懂的可以先看
并查集详解1
擒贼先擒王(并查集详解2)
#include<iostream>
using namespace std;
int f[1010];
int find(int v)
{
while(v!=f[v]) v=f[v];
return v;
}
int main()
{
int n,m,p1,p2,i,f1,f2;
while(scanf("%d",&n)&&n)//刚开始的时候,有n个城镇,一条路都没有,那么要修n-1条路才能把它们连起来
{
for(i=1;i<=n;i++) f[i]=i;//每个点互相独立,自成一个集合,从1编号到n //所以每个点的上级都是自己
scanf("%d",&m);//共有m条路
while(m--)
{//下面这段代码,其实就是join函数,只是稍作改动以适应题目要求
scanf("%d %d",&p1,&p2);
f1=find(p1);//每读入一条路,看它的端点p1,p2是否已经在一个连通分支里了
f2=find(p2);
if(f1!=f2)//如果是不连通的
{
f[f2]=f1;//那么把这两个分支连起来
n--;//分支的总数就减少了1,还需建的路也就减了1
}//如果两点已经连通了,那么这条路只是在图上增加了一个环
}//对连通性没有任何影响,无视掉
printf("%d\n",n-1);//最后输出还要修的路条数
}
return 0;
}