注意:两个城市之间可以有多条道路相通,也就是说
3 3
1 2
1 2
2 1
这种输入也是合法的
当N为0时,输入结束,该用例不被处理。
Output对每个测试用例,在1行里输出最少还需要建设的道路数目。
Sample Input
4 2 1 3 4 3 3 3 1 2 1 3 2 3 5 2 1 2 3 5 999 0 0Sample Output
1
0
2
998
Huge input, scanf is recommended.
Hint
Hint
分析
并查集,先初始化根节点为自己本身,否则会造成无法寻找到根节点
构建连通图,把所给数据连入连通图,形成原始并查集
循环遍历,寻找哪两座城市没有连通,连通之后继续寻找
#include<stdio.h>
int fd[1010],s[1010][2];
int find(int x)//并查集
{
if(fd[x]==x)
return x;
return fd[x]=find(fd[x]);
}
int main()
{
int m,n,i,j,t;
while(scanf("%d%d",&n,&m)&&n!=0)
{
for(i=1; i<=n; i++)//初始化根节点
fd[i]=i;
for(i=0; i<m; i++)
{
scanf("%d%d",&s[i][0],&s[i][1]);
int a=find(s[i][0]);
int b=find(s[i][1]);
if(a!=b)//合并组别
fd[a]=b;
}
t=0;
for(i=1; i<=n; i++)
for(j=1; j<=n; j++)
{
int a=find(i);//双向连通,所以寻找根节点,无需考虑所处层数
int b=find(j);
if(a!=b)//查找没有连通的两个村庄
{
t++;
fd[a]=b;//把它们联通, 避免重复计算
}
}
printf("%d\n",t);
}
return 0;
}