题目描述
思路讲解
大家看y总这段代码时要注意,在C操作时,y总先把a,b的根结点取出来了:a = find(a), b = find(b);,因此接下来是先将集合a接到集合b下再把a的连通块大小加到b上,还是先把a的连通块大小加到b上再操作集合都是可以的,如果大家没有提前一步的处理,就必须要先加连通块大小再操作集合,否则操作完集合后,a和b的根结点将会重叠,导致输出错误!
代码展示
#include <iostream>
using namespace std;
const int N = 100010;
int n, m;
int p[N], cnt[N]; //cnt用来记录每个集合的大小
int find(int x) {
if (p[x] != x) p[x] = find(p[x]);
return p[x];
}
int main() {
cin >> n >> m;
for (int i = 1; i <= n; i++) {
p[i] = i;
cnt[i] = 1; //刚开始cnt只有一个元素都是1
}
while (m--) {
string op;
int a, b;
cin >> op;
if (op == "C") {
cin >> a >> b;
a = find(a), b = find(b);
if (a != b) {
p[a] = b;
cnt[b] += cnt[a];
}
} else if (op == "Q1") {
cin >> a >> b;
if (find(a) == find(b)) puts("Yes");
else puts("No");
} else {
cin >> a;
cout << cnt[find(a)] << endl;
}
}
return 0;
}