原题链接: 837. 连通块中点的数量 - AcWing题库
1 . 初始化
void init()
{
for(int i = 1; i <= n; i++)
{
p[i] = i; p数组是祖宗数组, 初始时每个点的祖宗节点都是自己
size[i] = 1;
}
}
2 . 找祖宗
int find(int x)
{
if(p[x] == x) return x;
else return p[x] = find(p[x]);
}
3 . 合并连通块
void merge(int a, int b)
{
int x = find(a);
int y = find(b);
p[x] = y;
size[y] += size[x];
}
4 . 询问是否连通
bool ask(int a, int b)
{
return find(a) == find(b);
}
注意 size只有祖宗节点的有意义
完整代码:
#include<iostream>
using namespace std;
const int N = 1e5 + 5;
int n, m, a, b, p[N], size[N];
string op;
void init()
{
for(int i = 1; i <= n; i++)
{
p[i] = i;
size[i] = 1;
}
}
int find(int x)
{
if(x == p[x]) return x;
else return p[x] = find(p[x]); 新写法, 可以借鉴
}
void merge(int a, int b)
{
int x = find(a);
int y = find(b);
p[x] = y;
size[y] += size[x];
}
bool ask(int a, int b)
{
return find(a) == find(b);
}
int main()
{
cin >> n >> m;
init()
while(m --)
{
cin >> act;
if(act == "c")
{
cin >> a >> b;
if(!ask(a, b))
merge(a,b);
}
else if(act == "Q1")
{
cin >> a >> b;
ask(a, b) ? printf("Yes\n") : printf("No\n");
}
else
{
cin >> a;
printf("%d\n", size[find(a)]);
}
}
return 0;
}