并查集的模板 最简单的那种
并查集初始化
#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);
}
}