HDU 1232 畅通工程 并查集
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1232
题目大意:自行读题
解题思想:将连通的城市看做一个集合。通过数集合的个数求出需要修的路有多少。具体怎么实现集合的合并,看代码,代码有备注。
#include<iostream> #include<cstdio> using namespace std; int pre[1001];//pre[i]的意思是第i个点的祖先是pre[i]; int find(int x)//找祖先,并同时压缩路径,方便下一次找。 { int r=x; while(pre[r]!=r)//找祖先 r=pre[r]; int j; while(pre[x]!=r)//路径压缩,把当前节点到祖先点的所有点的祖先都直接指向祖先。 { j=pre[x]; pre[x]=r; x=j; } return r; } void connect(int a,int b)//连接两个集合 { int x=find(a); int y=find(b);//找到两个点的祖先。 if(x!=y)//比较两个点的祖先是否相同,即是否是同一个集合; pre[x]=y;//如果不是,将a点的祖先指向b点集合的祖先,这样a点的所有点最终的指向就是b点集合的祖先了,即完成了将a点的集合并入b集。 } int main() { int n,m; while(~scanf("%d",&n)) { int a,b,ans=0; if(n==0) break; scanf("%d",&m); for(int i=0;i<=n;i++)//初始化每个点,使每个点独立。 pre[i]=i; while(m--) { scanf("%d %d",&a,&b); connect(a,b); } for(int i=1;i<=n;i++) if(i==pre[i]) ans++; printf("%d\n",ans-1); } return 0; }