题目1012:畅通工程
/*
1.区分父节点 与 根
2.注意下标从1-->n.
*/
#include<stdio.h>
int a[1000];
int findRoot(int tmp) //理清 根 与父节点,别混淆。
{
if(a[tmp]==-1)
return tmp;
else{
int b=findRoot(a[tmp]); //把 父节点的树根 赋给临时变量,这是个递归过程。。
a[tmp]=b; //采用压缩路径的方法
return b;
}
}
int main()
{
int n,m,i,tmp1,tmp2,cnt;
//freopen("G:\\in.txt","r",stdin);
//freopen("G:\\our.txt","w",stdout);
while(scanf("%d",&n)!=EOF){
if(n==0)
break;
scanf("%d",&m);
for(i=0;i<1000;i++)
a[i]=-1; //先假设每个节点的根为一个不存在的结点:-1.
for(i=0;i<m;i++){
scanf("%d %d",&tmp1,&tmp2);
int p=findRoot(tmp1),q=findRoot(tmp2);
if(p!=q)
a[p]=q;
}
/*
两种方法求连通分支数:
第一种方法:看每个节点的 父节点 是否为-1.
*/
cnt=0;
for(i=1;i<=n;i++){
if(a[i]==-1)
cnt++;
}
/* 法2:根据每个节点的 树根 去计算,有多少个树根就有多少个连通分支。
ans[0]=findRoot(1); cnt=1;
int j,ans[1000];
for(i=2;i<=n;i++){
int tm=findRoot(i);
for(j=0;j<cnt;j++){
if(tm==ans[j])
break;
}
if(j==cnt)
ans[cnt++]=findRoot(i);
}
*/
printf("%d\n",cnt-1);
}
return 0;
}