定义:
并查集是一种特殊的数据结构,主要用于动态维护若干不重叠的集合。顾名思义,它包含两部分,一部分是合并,另一部分是查找。
模板:
1、首先,定义一个数组,用于记录一个数据集群中的各个元素之间的关系:
int pre[maxsize];///pre[i]表示,元素i归属于集群pre[i]
2、对数组中的元素进行初始化,使每个元素归属于自己:
void Init(){
for(int i=0;i<maxsize;i++)
pre[i]=i;
}
3、递归查找,寻找最原始的归属:
int Find(int x){
if(pre[x]==x)
return x;
else
return pre[x]=Find(pre[x]);///带有路径压缩
}
4、将具有关系的数据元素进行合并,将他们归属于最原始的祖先:
void Union(int x,int y){
int xx=Find(x);
int yy=Find(y);
if(xx<yy)///往较小方向集群,当然也可以往较大方向或者不规定方向
pre[yy]=xx;
else
pre[xx]=yy;
}
完整程序:
#include<bits/stdc++.h>
#define maxsize 10010
using namespace std;
int pre[maxsize];///记录元素归属
///初始化并查集
void Init(){
for(int i=0;i<maxsize;i++)
pre[i]=i;
}
///查找
int Find(int x){
if(pre[x]==x)
return x;
else
return pre[x]=Find(pre[x]);///带有路径压缩
}
///合并
void Union(int x,int y){
int xx=Find(x);
int yy=Find(y);
if(xx<yy)///往较小方向集群
pre[yy]=xx;
else
pre[xx]=yy;
}
int main(){
Init();
int n;///集群数或者关系数
cin>>n;
///输入具有关系的元素对
for(int i=0;i<n;i++){
int a,b;
cin>>a>>b;
Union(a,b);
}
///判断两个元素是否属于同一个集群
int x,y;
cin>>x>>y;
if(Find(x)==Find(y))
cout<<"Yes"<<endl;
else
cout<<"No"<<endl;
return 0;
}
测试数据:
6
1 2
2 3
1 4
5 8
4 9
5 7
1 9
输入的数据对中,前六组表明关系,1与2有关系,2又与3有关系,那么1与3借助2建立了关系也就是我们所说的属于同一个集群。前六组经过合并后,最终构成两个集群:
集群一:1 2 3 4 9
集群二:5 7 8
当查询1与9是否在同一个集群时,变显而易见了。
执行结果:
例题:
L2-024 部落 (25分) -------->解答
L3-003 社交集群 (30分) ------->解答