#include<stdc++.h>
#include <iostream>
using namespace std;
class ufset{
public:
static const int N = 100010;
int p[N]; // p[i]看做i的指针,该指针指向其父节点。
int cnt[N]; // cnt[i]看做i为root时候的树节点总个数。
ufset(int size){
for(int i = 0; i < size; i++){
p[i] = i; // 每个i都是root
cnt[i] = 1; // 每个i都是root,节点数为1
}
}
int find(int i){ //查找roor
if(p[i] != i){ // 如果当前节点不是root,
p[i] = find(p[i]);//找到其父节点的root,当前节点指向其父节点的root
}
return p[i]; // 当前节点的父节点一定为集合的root
}
bool isUnion(int le, int ri){ // 两个节点时候一个集合
return p[le] == p[ri]; //两节点的root是否相同
}
void unionD(int le, int ri){ // 合并两个集合
cnt[find(le)] += cnt[find(ri)]; //两集合节点数相加
p[find(ri)] = find(le);//右集合指向左集合的root
}
int cntI(int i){ // 计算当前集合数量
return cnt[find(i)];// 找到root,再找cnt[root]
}
};
int main(){
ufset us(10);
us.unionD(1,2);
us.unionD(3,2);
us.unionD(4,5);
us.unionD(6,5);
us.unionD(7,9);
cout << "find(): ";
for(int i = 1; i < 10; i++){
cout << us.find(i) << ",";
}
cout << endl << "p[]: ";
for(int i = 1;i < 10; i++){
cout << us.p[i] << ",";
}
cout << endl << "cnt[]: ";
for(int i = 1;i < 10; i++){
cout << us.cnt[i] << ",";
}
us.unionD(1,9); // 两个集合合并
cout << "两个集合合并:us.unionD(1,9);" << endl;
cout << endl << "p[]: ";
for(int i = 1;i < 10; i++){
cout << us.p[i] << ",";
}
cout << endl << "cnt[]: ";
for(int i = 1;i < 10; i++){
cout << us.cnt[i] << ",";
}
cout << endl << us.cntI(9);
cout << endl << "p[]: ";
for(int i = 1;i < 10; i++){
cout << us.p[i] << ",";
}
return 0;
}