数据结构(并查集)

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;
}

以上是关于数据结构(并查集)的主要内容,如果未能解决你的问题,请参考以下文章

树--12---并查集

数据结构与算法—并查集Kruskal算法求最小生成树

数据结构 ---[实现并查集(UnionFind)]

14 并查集

带权并查集——食物链

❤️数据结构入门❤️(2 - 5)- 并查集