1 #include<stdio.h> 2 int pre[1000]; 3 int find(int x) //查找根节点 4 { 5 int r=x; 6 while (pre[r]!=r) //返回根节点 r 7 r=pre[r]; 8 9 int i=x; int j; 10 while(i!=r) //路径压缩 11 { 12 j=pre[i]; 13 pre[i]=r; 14 i=j; 15 } 16 return r; 17 } 18 int main() 19 { 20 int n,m,p1,p2,i,total,f1,f2; 21 while(scanf("%d",&n) && n) //读入n,如果n为0,结束 22 { //刚开始的时候,有n个城镇,一条路都没有 //那么要修n-1条路才能把它们连起来 23 total=n-1; 24 //每个点互相独立,自成一个集合,从1编号到n //所以每个点的上级都是自己 25 for(i=1;i<=n;i++) { pre[i]=i; } 26 scanf("%d",&m); //共有m条路 27 while(m--) 28 { //下面这段代码,其实就是join函数,只是稍作改动以适应题目要求 29 //每读入一条路,看它的端点p1,p2是否已经在一个连通分支里了 30 scanf("%d %d",&p1,&p2); 31 f1=find(p1); 32 f2=find(p2); 33 //如果是不连通的,那么把这两个分支连起来 34 //分支的总数就减少了1,还需建的路也就减了1 35 if(f1!=f2) 36 { 37 pre[f2]=f1; 38 total--; 39 } 40 //如果两点已经连通了,那么这条路只是在图上增加了一个环 //对连通性没有任何影响,无视掉 41 } 42 //最后输出还要修的路条数 43 printf("%d ",total); 44 } 45 return 0; 46 }