题目描述
思路
if(find(a) == find(b)) continue;
siz[find(b)] += siz[find(a)];//在根节点上加上另一个树节点的古树
p[find(a)] = find(b);
把一个连通块想成一个集合,并开个
siz
数组记录俩个连通块的节点数,俩个连通块合并,也就是俩个siz
数组相加即可,但是要加在父亲结点上,注意顺序是先加根节点,在把父亲结点更新,还有如果a,b
在如果在同一个连通块,就不需要插入操作,直接continue
代码1
#include <bits/stdc++.h>
using namespace std ;
const int N = 100010;
int n, m;
int siz[N], p[N];
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;
siz[i] = 1;
}
char op[5];
while (m --) {
cin >> op;
int a, b;
if(op[0] == 'C') {
cin >> a >> b;
if(find(a) == find(b)) continue;
siz[find(b)] += siz[find(a)];//在根节点上加上另一个树节点的古树
p[find(a)] = find(b);
} else if(op[1] == '1') {
cin >> a >> b;
if(find(a) == find(b)) {
puts("Yes");
} else {
puts("No");
}
} else {
cin >> a;
cout << siz[find(a)] << endl;
}
}
return 0;
}