模板
定义
const int N=110;
int father[N];
初始化
for(int i=1;i<=n;i++){//首先让所有的个体都独自称为一个集合
father[i]=i;
}
查找-递归
int findFather(int x){
while(x!=father[x]){
x=father[x];
}
return x;
}
查找-迭代
int findFather(int x){
if(x==father[x])return x;
else return findFather(father[x]);
}
合并
- 判断2个元素是否为同一集合
- 一个元素的根节点指向另一结点
void Union(int a,int b){
int faA=findFather(a);
int faB=findFather(b);
if(faA!=faB){
father[faA]=faB;
}
}
针对查找也可进行路径压缩 后序将补充
例题
n个人 m个好朋友组数
问可以分为几个组
#include <cstdio>
const int N=110;
int father[N]; //存放父亲结点
bool isRoot[N];//是否是同一根结点
int findfather(int x){
if(x==father[x]) return x;
else{
return findfather(father[x]);
}
}
void Union(int a,int b){
int faA=findfather(a);
int faB=findfather(b);
if(faA!=faB){
father[faA]=faB;
}
}
void init(int n){
for(int i=1;i<=n;i++){
father[i]=i;
isRoot[i]=false;
}
}
int main(){
int n,m,a,b;
scanf("%d%d",&n,&m);
init(n);
for(int i=1;i<=m;i++){
scanf("%d%d",&a,&b);
Union(a,b);
}
for(int i=1;i<=n;i++){
isRoot[findfather(i)]=true;
}
int ans=0;
for(int i=1;i<=n;i++){
ans+=isRoot[i];
}
printf("%d",ans);
return 0;
}