[Acwing]836. 合并集合 原创

算法标签 并查集

题目简叙

在这里插入图片描述

思路

并查集:
1.将两个集合合并
2.查询两个元素是否在同一个元素当中

基本原理:每个集合用一颗树来表示,树根的编号就是当前集合的编号。每个节点存储它的父节点,p[x]表示x的父节点

问题1;:如何判断树根:if(p[x]==x)
这里非常重要的是:我们从一开始把所有p[x]=x了,这样一来,就可以用p[x]==x来判断是否是一个树的根节点
问题2:如何求X的集合编号:while(p[x]!=x)x=p[x];
如果不是根节点,就一直指向下一个,直到指向根节点为止
问题3:如何合并两个集合:p[find(a)]=find(b);
直接把一个树的根节点指向到另一个根节点即可

如图
在这里插入图片描述

代码

#include<iostream>

using namespace std;

int n,m;
const int N=1e5+10;
int p[N];//存储指向

int find(int n){
    if(p[n]!=n)p[n]=find(p[n]);//如果父节点不是初始化的且不是一个树根,那么就指向祖父节点,知道指向一个树根为止,同时路径上的所有节点都指向了根节点
    return p[n];//返回
}
int main(){
    cin>>n>>m;
    
    for(int i=0;i<n;i++)p[i]=i;//初始化,一共n个数字初始化有n个集合
    
    string op;//操作符
    int a,b;
    while(m--){
        cin>>op;
        cin>>a>>b;
        if(op[0]=='M'){
            p[find(a)]=find(b);//a的祖父节点,指向b的祖父节点,相当于集合a合并到集合b之中
        }   
        else {
            if(find(a)==find(b))cout<<"Yes";//如果指向的节点相同,证明在同一集合
            else cout<<"No";
            cout<<endl;
        }
    }
    
    return 0;
}




AC记录

在这里插入图片描述

posted @ 2024-08-14 16:27  俺叫西西弗斯  阅读(0)  评论(0)    收藏  举报  来源