837. 连通块中点的数量 题解

跳转链接

https://www.acwing.com/problem/content/839/ 来源:模板题

题目描述

给定一个包含 n 个点(编号为 1∼n)的无向图,初始时图中没有边。 现在要进行 m 个操作,操作共有三种: 1.C a b,在点 a 和点 b 之间连一条边,a 和 b 可能相等; 2.Q1 a b,询问点 a 和点 b 是否在同一个连通块中,a 和 b 可能相等; 3.Q2 a,询问点 a 所在连通块中点的数量;

输入格式 第一行输入整数 n 和 m。 接下来 m 行,每行包含一个操作指令,指令为 C a bQ1 a bQ2 a 中的一种。 输出格式 对于每个询问指令 Q1 a b,如果 a 和 b 在同一个连通块中,则输出 Yes,否则输出 No。 对于每个询问指令 Q2 a,输出一个整数表示点 a 所在连通块中点的数量 每个结果占一行。 数据范围 1 nn,mm 10^5^

输入样例
5 5 C 1 2 Q1 1 2 Q2 1 C 2 5 Q2 5 输出样例 Yes 2 3

题解思路

参考https://www.acwing.com/solution/content/5707/

代码

cpp
#include <iostream>
using namespace std;
const int N = 100010;

int n, m, a, b;
int p[N], cnt[N];
string op;

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++)  // 初始化,每个集合的根节点是自己,节点数量为1
	{
	    p[i] = i;
	    cnt[i] = 1;
	}
	
	while (m--)
	{
		cin >> op;
		if (op == "C")
		{
			cin >> a >> b;
			if (find(a) == find(b))	continue;  // 如果属于同一个集合,跳过
			cnt[find(b)] += cnt[find(a)];
			p[find(a)] = find(b);
		}
		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;
}
838. 堆排序 题解
836. 合并集合 题解
Valaxy v1.0.0-rc.3 驱动|主题-Yunv1.0.0-rc.3