AcWing 836. 合并集合(C++算法)
2020-07-30 17:38
260 查看
AcWing 836. 合并集合
1、题目(来源于AcWing):
一共有n个数,编号是1~n,最开始每个数各自在一个集合中。
现在要进行m个操作,操作共有两种:
“M a b”,将编号为a和b的两个数所在的集合合并,如果两个数已经在同一个集合中,则忽略这个操作;
“Q a b”,询问编号为a和b的两个数是否在同一个集合中;
输入格式
第一行输入整数n和m。
接下来m行,每行包含一个操作指令,指令为“M a b”或“Q a b”中的一种。
输出格式
对于每个询问指令”Q a b”,都要输出一个结果,如果a和b在同一集合内,则输出“Yes”,否则输出“No”。
每个结果占一行。
数据范围
1≤n,m≤105
输入样例:
4 5
M 1 2
M 3 4
Q 1 2
Q 1 3
Q 3 4
输出样例:
Yes
No
Yes
2、基本思想:
每一个集合用一棵树来表示。树根的编号就是整个集合的编号。每个节点存储它的父节点,p[x]表示x的父节点。
3、步骤:
①判断树根:if (p[x] == x)
②求x的树根节点:while (p[x] != x) p[x] = find(p[x])
③合并两个集合:p[find(a)] = find(b)
4、C++代码如下(该代码引用AcWing网站的代码):
#include <iostream> using namespace std; int find(int x); const int N = 100010; int n, m; int p[N]; int main() { cin >> n >> m; for (int i = 0; i < n; i ++ ) p[i] = i;//开始时每个元素是它自己的根节点 while (m -- ) { char op; int a, b; cin >> op >> a >> b; if (op == 'M') p[find(a)] = find(b);//令a的根节点等于b的根节点完成合并 else cout << ((find(a) == find(b)) ? "Yes" : "No") << endl; } return 0; } int find(int x)//找根节点 { if (p[x] != x) p[x] = find(p[x]); return p[x]; }//该代码引用AcWing网站的代码
相关文章推荐
- AcWing 835. Trie字符串统计(C++算法)
- ACwing 148. 合并果子
- AcWing 837. 连通块中点的数量(C++算法)
- JAVA List合并集合
- Acwing-99. 激光炸弹
- SPRING.NET 1.3.2 学习10--合并集合对象
- ACwing 90. 64位整数乘法
- AcWing - 220 - 最大公约数 = 积性函数筛
- AcWing - 199 - 余数之和 = 数论分块
- SQL查询集合合并成字符串
- scala合并有序集合
- C++算法之 合并两个数组
- 最全的C、C++算法集合
- 多个集合合并成没有交集的集合
- AcWing 102. 最佳牛围栏
- AcWing 畜栏预定
- 集合合并与拆分
- ACwing 93. 递归实现组合型枚举
- 链表的基本操作(创建,查找指定位置元素,删除指定元素,插入,倒置,去重,求集合的差,分别交换结点与交换结点值实现的冒泡排序,将两个有序链表合并成一个有序链表)c语言实现
- Acwing 263. 作诗