简介
并查集用于将许多元素加入不同的集合(join(x, y))来快速查找某个元素所在的集合。
每个集合有一个代表元素,查找(find(x))时如果两个元素的代表元素相同,则这两个元素属于同一个集合。
实现
集合通过pre数组将pre[i]赋值为i所在集合的代表元素。
初始化将每个元素的pre[i]赋为i,即各集合只有一个元素,自己为自己的代表元素。
通过join操作将两个元素合为一个集合,相应的两个元素所在的集合的所有元素也都合为一个集合。
通过find操作获取x元素的代表元素,并进行路径压缩,将所有元素都直接指向代表元素。
/**
* 并查集
*
* @桀骜 2018/8/21
*/
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
#define PRE_MAX 100
class DisjointSet {
private:
int pre[PRE_MAX];
public:
void init() {
for (int i = 0; i < PRE_MAX; i++) {
pre[i] = i;
}
}
void join(int x, int y) { //将x,y加入一个集合
int a = find(x), b = find(y);
if (a != b) {
pre[a] = b;
}
}
int find(int x) { //查找x所在集合的代表元素
int r = x;
while (pre[r] != r) {
r = pre[r];
}
int i = x, j;
while (i != r) { //路径压缩
j = pre[i];
pre[i] = r;
i = j;
}
return r;
}
};