下面的并查集模板以下标从1开始(下标为0可对应做出修改)
例题:力扣:1579
class UFD{
public:
int count = 0;
vector<int> father;
UFD(int count):count(count){
father = vector<int>(count+1, 0);
for(int i=0; i<father.size(); i++) father[i]=i;
}
void union_ij(int i, int j){
int pi = find(i);
int pj = find(j);
if(pi!=pj){
father[pj] = pi;
count--;
}
}
int find(int i){
int i_father = father[i];
if(i_father!=i){
father[i] = find(i_father);
}
return father[i];
}
bool connected(int i, int j){
int pi = find(i);
int pj = find(j);
return pi==pj;
}
};
模板二,根据size数组来减少查找父亲节点的路径,并定义隔离函数(isolate),用于把节点从集合移去,力扣2092
class UnionFind {
public:
vector<int> fathers;
vector<int> size;
UnionFind(int n) {
fathers = vector<int>(n);
iota(fathers.begin(), fathers.end(), 0);
size = vector<int>(n, 1);
}
int find(int i) {
return i == fathers[i] ? i : fathers[i] = find(fathers[i]);
}
bool connected(int i, int j) {
return find(i) == find(j);
}
void unin(int i, int j) {
int f_i = find(i);
int f_j = find(j);
if (f_i != f_j) {
if (size[f_i] < size[f_j]) swap(f_i, f_j);
fathers[f_j] = f_i;
size[f_i] += size[f_j];
}
}
void isolate(int x) {
if(x != fathers[x]){
fathers[x] = x;
size[x] = 1;
}
}
};