关于并查集,我们先引一个简单的问题
看完这个问题后我们再聊一聊并查集在其中的思想
.亲戚关系问题,给出N个人,对于这N个人,我们给出M起亲戚关系,然后询问任意两个人是否是亲戚,该怎么去判断呢?
#include<stdio.h>
#include<iostream>
using namespace std;
int N,M,Q;
int s[1000];
void initSet(){//并查集初始化
for( int i = 1; i <= N; i++){
s[i]=i;
}
}
int findSet(int x){//寻找根节点
while(x!=s[x])
{
x = s[x];
}
return x;
}
int unionSet(int x,int y){//合并集合
if(x!=y){
s[x] = y;
}
}
int main(){
while(~scanf("%d%d",&N,&M)){
initSet();//初始化
int a,b,sa,sb;
while(M--){
scanf("%d%d",&a,&b);
sa = findSet(a);
sb = findSet(b);
unionSet(sa,sb);
}/*这里把给出数据的根找出,然后将根合并,当集合里只有一个元素时只是将两个元素并入一个集合,换句话说,如果把单独的元素也看出集合的话,就是将两个集合建立关系*/
scanf("%d",&Q);
while(Q--){
scanf("%d%d",&a,&b);
sa = findSet(a);//找根
sb = findSet(b);
if(sa == sb)//将两个根进行比较
printf("属于同一集合/n");
else
printf("不属于同一集合/n");
}
}
}
我们模拟一下它的过程
A 1 2 3 4 5 6 7 8 9
S[a ] 1 2 3 4 5 6 7 8 9
这是一个初始化的集合,每个元素都单独存在;
我们把 3 4 并在一起
Find 3的根 为 3;
Find 4 的根为 4;
他们通过union函数合并之后,就如下;
A 1 2 3 4 5 6 7 8 9
S[a ] 1 2 3 3 5 6 7 8 9
将4 5 并在一起
A 1 2 3 4 5 6 7 8 9
S[a ] 1 2 3 3 3 6 7 8 9
将2 3并在一起
A 1 2 3 4 5 6 7 8 9
S[a ] 1 2 2 3 3 6 7 8 9
好,我们来findset,我们会发现,2,3,4,5findset找到的根都是2,同时也将他们并成了一个集合
这比较直观的体现了并查集合并的过程
希望对各位新coder有帮助,谢谢。