合并集合(C++)题解

题干:

一共有 nn 个数,编号是 1∼n1∼n,最开始每个数各自在一个集合中。

现在要进行 mm 个操作,操作共有两种:

  1. M a b,将编号为 aa 和 bb 的两个数所在的集合合并,如果两个数已经在同一个集合中,则忽略这个操作;
  2. Q a b,询问编号为 aa 和 bb 的两个数是否在同一个集合中;
输入格式

第一行输入整数 nn 和 mm。

接下来 mm 行,每行包含一个操作指令,指令为 M a b 或 Q a b 中的一种。

输出格式

对于每个询问指令 Q a b,都要输出一个结果,如果 aa 和 bb 在同一集合内,则输出 Yes,否则输出 No

每个结果占一行。

数据范围

1≤n,m≤1051≤n,m≤105

输入样例:
4 5
M 1 2
M 3 4
Q 1 2
Q 1 3
Q 3 4
输出样例:
Yes
No
Yes

代码:

#include 
#include 
#include 

using namespace std;

const int N = 100010;

int p[N];//存放代表元素

//查找 x 所属的集合,就是 x 元素的代表元素
int find(int x)
{
    //如果 x 的代表元素不是他自己,就递归的x的代表元素修改为代表元素的代表元素
    if(x != p[x]) p[x] = find(p[x]);

    return p[x];
}

//合并a b所在的两个集合
void merge(int a, int b)
{
    int pa = find(a);//找到 a 所在集合的代表元素
    int pb = find(b);//找到 b 所在集合的代表元素
    if(pa != pb)//如果不是同一个,则属于不同集合,需要合并
    {
        p[pa] = pb;//将a所在集合代表元素的代表元素设置为b所在集合的代表元素。
    }
}


void query(int a,int b)
{
    int pa = find(a);//找到 a 所在集合的代表元素
    int pb = find(b);//找到 b 所在集合的代表元素
    //判断 a 和 b 是否有同一个代表元素
    if(pa == pb) cout << "Yes" << endl;
    else cout << "No" << endl;
    return ;
}
int main()
{
    int n, m;
    cin >> n >> m;
    //初始化代表元素集合,开始的时候,各自属于一个集合,即每个元素的代表元素是他自己。
    for (int i = 1; i <= n; i ++ )
        p[i] = i;

    while (m -- )
    {
        char op;
        cin >> op;
        int a, b;
        cin >> a >> b;

        if(op == 'M')
        {//合并
            merge(a, b);
        }
        else
        {//查询
            query(a, b);
        }
    }
}

 

你可能感兴趣的:(c++,算法,图论)