什么情况下我们需要并查集?
将两个集合合并
询问两个元素是否在一个集合当中
并查集怎么写?
基本原理:
用树的形式来维护每个集合,每个集合的根节点的编号作为它的代表元素
对于树的每个结点,都要用数组p存储确定它的父节点
如何判断某个结点是否为根节点?
根节点的父节点为它自身
if(p[x]==x)
如何求x的集合编号,即它属于哪个集合?
while(p[x]!=x)//没有到达根节点
x=p[x];//就一直向上追溯
如何合并两个集合
p[x]为x的集合编号,p[y]为y的集合编号,令p[x]=y即可
并查集的优化方法
路径压缩
直接将父节点指向根节点
按址合并
代码实现
#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]);
return p[x];
}
int main()
{
int n,m;//n个结点,m步操作
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++) p[i]=i;
//起初,每个结点是一个集合,所以每个结点的父节点是自己
while(m--)
{
int a,b;
char c[2];
scanf("%s%d%d",c,&a,&b);
if(c=="M")//集合合并
{
p[b]=a;//将以b为根节点的树合并到以a为根节点的树上
}
else if(c=="Q")//询问是否在同一个集合中
{
//ask(a,b);
if(find(a)==find(b))//如果ab的根节点相同则在同一个集合中
puts("Yes");
else puts("No");
}
}
return 0;
}
并查集是一种用于处理一些不相交集合的合并与查询的数据结构。文章介绍了并查集的基本操作,包括查找根节点、合并集合以及询问元素是否在同一集合中。此外,还提到了并查集的优化策略——路径压缩和按址合并,以及其实现代码示例。
25万+

被折叠的 条评论
为什么被折叠?



