//简单模板
class Union_find{
public:
Union_find(int n):f(n,0){for (int i = 0; i < f.size(); i++)f[i] = i;}
void add(int x, int y){int fa = find(x), fb = find(y);if (fa != fb)f[fa] = fb;}
int find(int x){return x == f[x] ? x : f[x] = find(f[x]);}
bool check(int x,int y){
return find(x) == find(y);
}
private:
vector<int> f;
};
//计算数量
class Union_find{
public:
Union_find(int n){
f.assign(n, 0);
cnt.assign(n, 0);
for (int i = 0; i < f.size(); i++)f[i] = i;
}
void add(int x, int y){
int fa = getFa(x), fb = getFa(y);
if (fa != fb){
f[fa] = fb;
cnt[fb] += cnt[fa] + 1;
}
}
//
int getFa(int x){
return x == f[x] ? x : f[x] = getFa(f[x]);
}
int getCnt(int x){
return cnt[x];
}
private:
vector<int> f, cnt;
};
//按秩合并
class Union_find{
public:
Union_find(int n){
f.assign(n, 0);
rank.assign(n,0);
for (int i = 0; i < f.size(); i++)f[i] = i;
}
void merge(int x, int y) {
int rx = find(x);
int ry = find(y);
if (rx != ry) {
if (rank[rx] > rank[ry]) {
f[ry] = rx;
} else if (rank[rx] < rank[ry]) {
f[rx] = ry;
} else {
f[ry] = rx;
rank[rx]++;
}
}
}
//
int find(int x){
return x == f[x] ? x : f[x] = find(f[x]);
}
private:
vector<int> f,rank;
};