并查集

并查集的作用:

①合并两个集合

②查询两个元素是否在一个集合中

实现形式:

用树的形式来维护所有的集合

 

根节点的编号等于当前集合的编号

对于每一个点存储一它的父结点,p[x]表示x的父结点

对于一个点是否在一个集合中,从这个点往上找,找对应的父结点,最后找到树根这个点,树根的编号就是集合的编号、

问题1:如何判断是否是树根:

if(p[x]==x)

因为除了根结点之外,所有的点都不等于父节点

问题2:如何求x扽集合编号:

一直往上走直到树根:while(p[x]!=x) x=p[x]

问题3:如何合并两个集合;

直接把一个集合插到另一个集合里面,作为另一个集合的儿子

 

 

 px是x的集合编号,py是y的集合编号

p[x]表示x的父节点,那把一棵树作为整体,加入到另一棵树上,p[x]=y,实质上也就是,本来两个不同的集合编号现在要合并为一个,让走到树根的集合编号相同就可以了

优化:(路径压缩)

把本来需要一个个往上走的点全都都指向根节点

 

 

 

 

 

 

 

一共有 nn 个数,编号是 1n1∼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

每个结果占一行。

数据范围

1n,m1051≤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>
using namespace std;
const int N=100010;
int p[N];//代表某个数的父节点 
int find(int x)//表示查找x的根节点+路劲压缩 
{
    if(p[x]!=x) p[x]=find(p[x]);//如果这个数不是根节点(p[x]==x),那就继续递归 
    //else if(p[x]==x)//这里加上一句话应该会好理解很多,
    return p[x];// 就是在不停的递归之后发现递归到根节点了,那就直接返回根节点也做到了路径压缩
}
int main(){
    int n,m,t;
    cin>>n>>m;
    for(int i=1;i<=n;i++)
        p[i]=i;//因为刚开始的时候,集合里只有当前一个数自己本身。根节点等于x,初始化根节点
    while(m--)
    {
        char ch;
        int a,b;
        cin>>ch>>a>>b;
        if(ch=='M') p[find(a)]=find(b); //这句话字面意思就是b的根节点的编号变成a的根节点的编号
        else
        {
            if(find(a)==find(b)) cout<<"Yes"<<endl;
            else cout<<"No"<<endl;
        }
    }
    return 0; 
}
复制代码

 稍微改了一下写法,改成自己习惯的,嘻嘻

复制代码
#include<iostream>
using namespace std;
const int N=100010;
int p[N];
int find(int x)
{
    if(p[x]!=x) p[x]=find(p[x]);
    else return p[x];
}
int main(){
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++)
        p[i]=i;
    while(m--)
    {
        char ch;
        int a,b;
        cin>>ch>>a>>b;
        if(ch=='M') p[find(a)]=find(b);
        else
        {
            if(find(a)==find(b)) cout<<"Yes"<<endl;
            else cout<<"No"<<endl;
        }
    }
    return 0;
}
复制代码

 

posted @   小志61314  阅读(89)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示