并查集
- 结构:用树形结构来实现,每个元素表示一个节点,每个组是一棵树。
- 查询:可以查询两个元素是否在一个组,从结点开始往上找,看根节点是否相同。均摊查询复杂度是O(n)。
- 合并:可以将两个组 合并为一个组,将树的根节点相连接。
(1)树的高度小的向高度大的连边
(2)路径压缩(每次查找时,查询过程中向上经过的所有结点都修改为直接指向根,但为了简单不修改树的高度)
代码实现
- 初始化
- 查找根节点
- 合并操作
- 判断是否属于同一个集合
#include<iostream>
#define N 9999
using namespace std;
int par[N];
int rank[N];
void init(int n) {
for(int i=0; i<n; i++) {
rank[i]=0;
par[i]=i;
}
}
int find (int x) {
if(par[x]==x) {
return x;
} else {
return par[x]=find(par[x]);
}
}
void unite(int x,int y) {
x=find(x);
y=find(y);
if(x==y)
return;
if(rank[x]<rank[y]) {
par[x]=y;
} else {
par[y]=x;
if(rank[x]==rank[y])
rank[x]++;
}
}
bool same(int x,int y){
return find(x)==find(y);
}