hdu 1232畅通工程 并查集(入门题)
并查集水题。。先来点并查集基础。。查找函数:
int find(int i)
{
int t=i;
while(bin[t]!=t)
t=bin[t];
return t;
{
int t=i;
while(bin[t]!=t)
t=bin[t];
return t;
} 没有路径压缩
int find(int i)
{
int k,t;
t=i;
while(t!=bin[t])
t=bin[t];
while(i!=t) //修改路径---压缩
{
k=bin[i];
bin[i]=t;
i=k;
}
return i;
{
int k,t;
t=i;
while(t!=bin[t])
t=bin[t];
while(i!=t) //修改路径---压缩
{
k=bin[i];
bin[i]=t;
i=k;
}
return i;
} 带有路径压缩
还有一个递归路径压缩查找:
int find(int x)
{
return father[x]-x ? father[x]=find(father[x]) : x;
}
分析:把已连通的公路通过并查集算法合并到一个集合。。然后通过查找有多少个不同的集合就能知道还有多少条路需要建设。。
本题代码:
#include<iostream> using namespace std; int father[1001]; int find(int x) { return father[x]-x ? father[x]=find(father[x]) : x; } void unio(int x, int y) { if(find(x)-find(y)) father[find(x)]=find(y); } int main() { int n, m, i, x, y, sum; while(scanf("%d",&n) && n) { for(i=1; i<=n; i++) { father[i]=i; } scanf("%d",&m); for(i=1; i<=m; i++) { scanf("%d%d",&x,&y); unio(x, y); } for(sum=-1,i=1; i<=n; i++) { if(father[i]==i) sum++; } cout<<sum<<endl; } return 0; }