并查集的模板 最简单的那种
并查集初始化
#include<stdio.h>
int father[1005];
void init(int m){
int i;
for(i=1;i<=m;i++) father[i]=i;
}
并查集找根(不改find father 不进行压缩)
int find(int x){
while(x!=father(x)) x=father[x];
return x;
}
并查集找根 (改find 执行一次后 find函数直接改变 好像没卵用。。。)
void find(int x){
return x==father(x)?x:find(x);
}
并查集找根(改father 路径压缩)
递归版
int find(int x){
if(x!=father[x])
father[x]=find(father[x]);
return father[x];
}
非递归版
int find(int x){
int fa,temp;
fa=x;
while(x!=father[x])
x=father[x];
while(fa!=x){
temp=father[fa];
father[fa]=x;
fa=temp;
}
return x;
}
并查集合并
void merge(int x,int y){
x=father[x];
y=father[y];
if(x!=y) father[y]=x;
}
并查集判断是否同根
void same(int x,int y){
return father[x]==father[y];
}
例题hduoj1232
代码如下:
#include<stdio.h> #define N 1005 int father[N]; void init(int x){ int i; for(i=1;i<=x;i++) father[i]=i; } int find(int x){ while(x!=father[x]) x=father[x]; return x; } void merge(int x,int y){ x=find[x]; y=find[y]; if(x!=y) father[y]=x; } int main(){ int n,m,a,b,sum,i; while(scanf("%d%d",&n,&m)!=EOF&&n){ init(n); for(i=0;i<m;i++){ scanf("%d%d",&a,&b); merge(a,b); } sum=0; for(i=1;i<=n;i++) if(i==father[i]) sum++; printf("%d",sum-1); } }
转自:https://blog.csdn.net/la_pereza/article/details/54959185