数据结构(并查集)
Posted 芜湖之肌肉金轮
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构(并查集)相关的知识,希望对你有一定的参考价值。
并查集
并查集是一种怎么样的数据结构呢?
1.处理集合合并
2.对集合元素进行查找
同时并查集对集合元素进行查找的时候,会把路径上所有的点全部都指向父节点,这样就可以把整个查询工作近似的优化成o(1),这就是大家常说的路径压缩
其实说了那么多已经把并查集的最最基础的思路讲出来了,我们找一题试试
(题目来源acwing)
首先啊,并查集的时候要提前进行初始化
int q[N];
for(int i=0;i<n;i++)q[i]=i;
那么接下来呢?
首先我们考虑下几个问题
第一个问题:如何判断树结点,根据我们初始化来看我们可以用 q[ i ] == i 来判断
第二个问题:如何找到 某个数(X)的编号 ,也是根据初始化我们可以知道我们可以用
while(q[ x ] != x)x = q[ x ](这样可以求最终的父节点) 这里我们可以用递归的方式把路径上所有的点都只向最终得父节点(路径压缩)
第三个问题:我们应该怎么合并两个集合?这个问题我们根据前两个问题的答案就可以知道了直接比如一个x和一个y我们直接p[ x ] = y,为什么呢因为我们已经知道y是某个集合的最终父节点,该集合所有元素都指向y,根据初始化,p[x]最终存的也是x的最终结点,只要让x的最终结点指向y借可以了
好问题想完了我们来看看代码怎么写:
#include<iostream>
using namespace std;
const int N=1000100;
int n,m;
int q[N];
int find(int x)
{
if(q[x]!=x)return q[x]=find(q[x]);//把路径上每个点都指向父节点
return x;
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)q[i]=i;
while(m--)
{
char cha[2];
int a,b;
scanf("%s%d%d",cha,&a,&b);
if(cha[0]=='Q'){if(find(a)==find(b)) puts("Yes");
else puts("No");
}
else
q[find(a)]=q[find(b)];//找到双方父节点合并起飞
}
return 0;
}
以上是关于数据结构(并查集)的主要内容,如果未能解决你的问题,请参考以下文章