【算法】【并查集】acwing算法基础837. 连通块中点的数量

ops/2025/3/3 21:53:56/

题目

给定一个包含 n 个点(编号为 1∼n)的无向图,初始时图中没有边。

现在要进行 m 个操作,操作共有三种:

C a b,在点 a 和点 b 之间连一条边,a和 b 可能相等;Q1 a b,询问点 a 和点 b 是否在同一个连通块中,a 和 b
可能相等; Q2 a,询问点 a 所在连通块中点的数量;

输入格式

第一行输入整数 n 和 m。

接下来 m 行,每行包含一个操作指令,指令为 C a b,Q1 a b 或 Q2 a 中的一种。

输出格式

对于每个询问指令 Q1 a b,如果 a 和 b 在同一个连通块中,则输出 Yes,否则输出 No。

对于每个询问指令 Q2 a,输出一个整数表示点 a 所在连通块中点的数量

每个结果占一行。

数据范围

1≤n,m≤105

输入样例:

5 5

C 1 2

Q1 1 2

Q2 1

C 2 5

Q2 5

输出样例:

Yes

2

3

来源:acwing算法基础837. 连通块中点的数量


思路(注意事项)


纯代码

#include<bits/stdc++.h>
using namespace std;const int N = 100010;
int p[N], si[N];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;si[i] = 1;}while (m --){char c[2];int a, b;scanf("%s", c);if (c[0] == 'C') {	scanf("%d%d", &a, &b);if (find(a) == find(b)) continue;si[find(b)] += si[find(a)];p[find(a)] = find(b);}else if (c[1] == '1'){scanf("%d%d", &a, &b);if (find(a) == find(b)) cout << "Yes" << endl;else cout << "No" << endl;}else {scanf("%d", &a);cout << si[find(a)] << endl;}}return 0; 
}

题解(带注释)

#include<bits/stdc++.h>
using namespace std;const int N = 100010; // 定义最大节点数
int p[N]; // 并查集数组,p[i] 表示节点 i 的父节点
int si[N]; // 存储每个集合的大小,si[i] 表示以 i 为根节点的集合的大小// 查找函数,用于查找节点 x 的根节点,并进行路径压缩
int find(int x)
{// 如果 x 不是根节点,递归查找其父节点的根节点,并进行路径压缩if (p[x] != x) p[x] = find(p[x]);// 返回 x 的根节点return p[x];
}int main()
{int n, m; // n 表示节点数,m 表示操作数cin >> n >> m; // 输入节点数和操作数// 初始化并查集for (int i = 1; i <= n; i++) {	p[i] = i; // 每个节点的父节点初始化为自己si[i] = 1; // 每个集合的大小初始化为 1}// 处理每个操作while (m --){char c[2]; // 操作类型int a, b; // 操作涉及的两个节点scanf("%s", c); // 输入操作类型if (c[0] == 'C') // 如果是合并操作{	scanf("%d%d", &a, &b); // 输入要合并的两个节点if (find(a) == find(b)) continue; // 如果已经在同一个集合中,跳过si[find(b)] += si[find(a)]; // 将 a 所在集合的大小加到 b 所在集合的大小上p[find(a)] = find(b); // 将 a 所在集合的根节点的父节点设置为 b 所在集合的根节点}else if (c[1] == '1') // 如果是查询操作(查询两个节点是否在同一个集合中){scanf("%d%d", &a, &b); // 输入要查询的两个节点if (find(a) == find(b)) cout << "Yes" << endl; // 如果在同一个集合中,输出 Yeselse cout << "No" << endl; // 否则输出 No}else // 如果是查询操作(查询某个节点所在集合的大小){scanf("%d", &a); // 输入要查询的节点cout << si[find(a)] << endl; // 输出该节点所在集合的大小}}return 0; 
}

http://www.ppmy.cn/ops/162876.html

相关文章

学习第九天-栈

栈的定义&#xff1a;栈是一种线性表数据结构&#xff0c;仅允许在表的一端&#xff08;栈顶&#xff09;进行插入&#xff08;入栈&#xff09;和删除&#xff08;出栈&#xff09;操作。没有数据元素时为「空栈」&#xff0c;遵循「后进先出&#xff08;LIFO&#xff09;」原…

做表格用什么软件?VeryReport让数据管理更高效!

在日常办公和企业管理中&#xff0c;表格软件是必不可少的工具&#xff0c;无论是财务报表、销售数据、库存管理&#xff0c;还是市场分析&#xff0c;都离不开高效的数据处理和可视化展示。那么&#xff0c;做表格用什么软件最好&#xff1f;市面上有Excel、WPS、Google Sheet…

StrokesPlus【电脑鼠标键盘手势软件】v0.5.8.0 中文绿色便携版

前言 StrokesPlus.net是一个超方便的手势识别软件&#xff0c;它能帮你用手势来代替鼠标和键盘操作。用起来既简单又灵活&#xff0c;功能还特别强大。 操作起来非常简单&#xff0c;它有好多实用的功能&#xff0c;比如智能识别你写的字、设定手势操作的区域、模拟鼠标的各种…

android bp构建编译C++代码

Android BP 编译方式介绍 在 Android 构建系统中&#xff0c;Blueprint&#xff08;简称 BP&#xff09;是一种基于 JSON 的构建配置文件格式&#xff0c;代替了传统的 Android.mk 文件。Blueprint 文件的主要扩展名是 .bp&#xff0c;它是 Android 的 Soong 构建系统所使用的…

长时间目标跟踪算法(2)-LCT目标跟踪算法

LCT算法的原始论文和源码已开源&#xff0c;原始论文和源码打包下载。 目录 算法简介核心思路与基本原理 2.1 任务分解&#xff1a;平移与尺度估计2.2 时间上下文相关滤波模型2.3 目标外观相关滤波模型2.4 在线随机蕨分类器 实现方案 3.1 关键公式与频域加速3.2 伪代码与流程…

webpack5在生产环境屏蔽掉控制台打印 失效处理

常规是使用 const TerserPlugin require(terser-webpack-plugin)const terserUglifyPlugin new TerserPlugin({exclude: [/node_modules/],terserOptions: {parse: {},compress: {warnings: false,drop_console: true,drop_debugger: true},output: {comments: false,beauti…

蓝桥杯单片机组第十二届省赛第二批次

前言 第十二届省赛涉及知识点&#xff1a;NE555频率数据读取&#xff0c;NE555频率转换周期&#xff0c;PCF8591同时测量光敏电阻和电位器的电压、按键长短按判断。 本试题涉及模块较少&#xff0c;题目不难&#xff0c;基本上准备充分的都能完整的实现每一个功能&#xff0c;并…

【愚公系列】《Python网络爬虫从入门到精通》038-SQLite数据库

标题详情作者简介愚公搬代码头衔华为云特约编辑,华为云云享专家,华为开发者专家,华为产品云测专家,CSDN博客专家,CSDN商业化专家,阿里云专家博主,阿里云签约作者,腾讯云优秀博主,腾讯云内容共创官,掘金优秀博主,亚马逊技领云博主,51CTO博客专家等。近期荣誉2022年度…