目前仅将自己学习acwing的课程进行整理
acxing的板子
#include <iostream>
#include <string>
using namespace std;
const int N=100010;
int p[N]; // 保存集合的编号也就是父节点
int s[N]; // 集合大小 一个集合就是一个连通块注意理解p[n]和s[n]的作用即可
int n,m;
int find(int x) // 查找x的祖宗节点 祖宗节点的特性是 x=p[x] --- 1=p[1] 本身
{
if(x!=p[x]) p[x]=find(p[x]);
return p[x];
}
int main()
{
cin >> n >> m;
for(int i=1;i<=n;i++)
{
p[i]=i; // 初始化每个数都属于一个集合 祖宗节点都是本身
s[i]=1; // 初始化每个连通块起初大小都为1
}
while(m--)
{
string op;
int a,b;
cin >> op;
if(op=="C")
{
cin >> a >> b;
if(find(a) != find(b))
{
s[find(b)]+=s[find(a)]; // 合并两个集合的大小 成为一个连通块
p[find(a)] = find(b); // 先合并大小 再合并两个集合 顺序不能相反
}
}
else if(op=="Q1")
{
cin >> a >> b;
if(find(a) == find(b)) cout << "Yes" << endl;
else cout << "No" << endl;
}
else
{
cin >> a;
cout << s[find(a)] << endl;
}
}
return 0;
}
洛谷的模板
#include <iostream>
using namespace std;
const int N = 10010;
int p[N];
// 路径压缩的find函数
int find(int x) {
if (p[x] != x) {
p[x] = find(p[x]);
}//如果没找到一直寻找父节点
return p[x];
}
int main() {
int n, m;
cin >> n >> m;
for (int i = 1; i <= n; i++) p[i] = i;
while (m--) {
int op, a, b;
cin >> op >> a >> b;
if (op == 2) {
if (find(a) == find(b)) {
puts("Y");
} else {
puts("N");
}
}
if (op == 1) {
p[find(a)] = find(b);
}
}
return 0;
}
测试样例
4 7
2 1 2
1 1 2
2 1 2
1 3 4
2 1 4
1 2 3
2 1 4