0
点赞
收藏
分享

微信扫一扫

并查集【模板】

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

作用:

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 条评论