0
点赞
收藏
分享

微信扫一扫

并查集【模板】

老罗话编程 2022-01-26 阅读 32
数据结构

作用:

1:将两元素合并,

2:访问两元素是否在同一个集合中。

举个例子:

给定2个数1 2;

集合编号分别为1 2;

先查询1与2是否在同一集合,此时1与2不在一个集合;

接下来将1与2所在集合1与集合2合并,集合2-->集合1;

集合编号为1 1;

此时查询1与2是否在同一集合,那1与2都在集合1中。

那么如何实现捏,首先要解决三个问题

问题:1,如何判断根节点:--->if(p[x]==x)

问题:2,如何求x的集合编号:--->while(p[x]==x) x=p[x]

问题:3,如何合并两个集合:将两个集合的根节点合二为一,操作如下:x是集合X的编号;y是集合Y的编号。--->p[x]=y。

基于上述三个问题

给出核心代码

1,初始化,返回x所在集合编号+路径压缩(代码如下)

这里需要简单说明一下路径压缩:

查找某个元素的根的时候,让从此元素到根的路径上的每一个节点都设置根为父节点

for (int i=1;i<=n;i++) p[i]=i;//初始化节点

int find(int x)//返回x所在集合编号+路径压缩
{
    if (p[x]!=x) p[x]=find(p[x]);
    return p[x];
}

2,合并操作

if(合并操作条件)
{
     p[find(a)]=find(b);
}

3,查询操作

if(查询操作条件)
{
       if (find(a)==find(b))//判断两集合所在编号是否相同 
           puts("Y");
       else
           puts("N");
}

那我们结合实际题目看一下

原题链接:P3367 【模板】并查集 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

代码如下:

#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]);
    return p[x];
}

int main()
{
    int n, m;
    cin>>n>>m;
    for (int i=1;i<=n;i++) p[i]=i;//初始化节点

    while (m--)
    {
        int q;//本次操作的操作类型
        cin>>q;
        int a,b;
        cin>>a>>b;
        if(q==1)//合并操作(q==1)
        {
            p[find(a)]=find(b);
        }
        else//查询操作(q==2)
        {
            if (find(a)==find(b))//判断两集合所在编号是否相同 
                puts("Y");
            else
                puts("N");
        }
    }
    return 0;
}
举报

相关推荐

0 条评论