合并集合


题目

一共有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

分析

这是并查集的模板题,
并查集就是可以快速的判断两个数字是不是在一个集合里,以及合并两个集合。

代码

#include<iostream>
#include<cstring>
using namespace std;

int fa[123456];

int find(int x)
{  //路径压缩优化
    if(fa[x]!=x) fa[x]=find(fa[x]);
    return fa[x];
}

int main()
{
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++) fa[i]=i;
    while(m--)
    {
        string s;int a,b;
        cin>>s>>a>>b;
        if(s=="M") fa[find(a)]=find(b);  //将a合并到b集合
        else if(s=="Q") 
        {
            if(find(a)==find(b)) cout<<"Yes"<<endl;
            else cout<<"No"<<endl;
        }
    }
    return 0;
}

Author: 眼里有星星
Reprint policy: All articles in this blog are used except for special statements CC BY 4.0 reprint polocy. If reproduced, please indicate source 眼里有星星 !
 Previous
模拟栈 模拟栈
题目实现一个栈,栈初始为空,支持四种操作:(1) “push x” – 向栈顶插入一个数x;(2) “pop” – 从栈顶弹出一个数;(3) “empty” – 判断栈是否为空;(4) “query” – 查询栈顶元素。现在要对栈进行M个操
2020-02-22
Next 
单链表 单链表
题目实现一个单链表,链表初始为空,支持三种操作:(1) 向链表头插入一个数;(2) 删除第k个插入的数后面的数;(3) 在第k个插入的数后插入一个数现在要对该链表进行M次操作,进行完所有操作后,从头到尾输出整个链表。注意:题目中第k个插入的
2020-02-22
  TOC