畅通工程
#include <bits/stdc++.h> using namespace std; int pre[1010]; bool t[1010];//t 用于标记独立块的根结点 int find(int x)//查找根节点 { int r=x; while(pre[r]!=r) r=pre[r];//返回根节点 r int i=x,j; while(pre[i]!=r)//路径压缩 { j=pre[i]; // 在改变上级之前用临时变量 j 记录下他的值 pre[i]=r;//把上级改为根节点 i=j; } return r; } void join(int x,int y)//判断x y是否连通, { int fx=find(x),fy=find(y); if(fx!=fy) pre[fy]=fx;//如果已经连通,就不用管了 //如果不连通,就把它们所在的连通分支合并起来 } int main() { int N,M,a,b,i,j,ans; while(scanf("%d%d",&N,&M)&&N) { for(i=1;i<=N;i++) pre[i]=i;//初始化 for(i=1;i<=M;i++) { scanf("%d%d",&a,&b); join(a,b);//判断x y是否连通 } memset(t,0,sizeof(t)); for(i=1;i<=N;i++) t[find(i)]=1;//标记根结点 for(ans=0,i=1;i<=N;i++) if(t[i]) ans++; printf("%d\n",ans-1); } return 0; }