将至少要修的道路初始化为n-1:连通n个点最少需要n-1条边.判断当前两个节点pp和qq是不是在同一个集合中(并查集的功能:查找可以做到),如果不在同一个集合,连通两个集合,相当于修建一条路, cnt--;如果在一个集合中,不对它处理即可
#include<cstdio>
#include<iostream>
using namespace std;
const int maxn=1005;
int pre[maxn];
int cnt;
int n,m;
void init()
{
for(int i=0; i<=n; i++)
pre[i]=i;
cnt=n-1;
}
int finds(int x)
{
if(x==pre[x])
return pre[x];
pre[x]=finds(pre[x]);
return pre[x];
}
void unions(int a,int b)
{
int x=finds(a);
int y=finds(b);
if(x==y);
else
{
pre[x]=y;
cnt--;
}
}
int main()
{
int pp,qq;
while(~scanf("%d",&n))
{
if(n==0)break;
scanf("%d",&m);
init();
for(int i=0; i<m; i++)
{
scanf("%d%d",&pp,&qq);
unions(pp,qq);
///printf("至少要修的道路数目更新为%d\n",cnt);
}
printf("%d\n",cnt);
}
return 0;
}