[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记录

 
                    
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号