首页 > 其他 > 详细

并查集

时间:2019-08-11 21:41:53      阅读:125      评论:0      收藏:0      [点我收藏+]

并查集是一种树型的数据结构,用于处理一些不相交集合的合并及查询问题。常常在使用中以森林来表示。


一,对并查集的认识
并查集是树形结构,常常在题目中用来判断两个元素是否属于同一个集合,每个集合都有一个特征性元素称为这个集合的father,如果两个元素的father相同,则说明这两个元素属于同一集合,若这两个元素的father不相同,则说明这两个元素不属于一个集合。并查集就是这样一种支持合并和查询的树形数据结构。在题目中的应用有,判断两个点是否属于同一个联通块,最小生成树kruskal算法中,判断加边是否会有环等。
在考察并查集的题目中,一般我们用一个f数组来实现并查集的功能,起初所有的f[i]=i;证明所有元素都是单独一个集合。

//并查集初始化
for(int i=1;i<=n;i++) f[i]=i;

二,并查集的基本操作
1,并查集的合并操作(merge)
简而言之,就是将两个元素所在的集合合并成一个集合,操作简单,首先我们只需要找到两个集合的特征性元素,然后把其中一个特征性元素变成另一个,这样两个集合特征性元素相同,两个集合就合并在了一起,在merge操作中我们运用到了按秩合并来优化。

inline void merge(int f1,int f2)
{
f[f1]=f2;
return; }//普通合并

按秩合并:所谓秩就是树高,按秩合并就是按照秩序合并,起初我们给每个点赋高为一,以后在每次合并的过程中,都用树高小的指向树高大的,这样可以保证树高不超过log2N,把查询的最坏复杂度从O(n)减小到O(logn)。

inline void merge(int x,int y)
{
    int f1=find(x);
    int f2=find(y);
    if(f1!=f2)
    {
        if(rank[x]<=rank[y]) f[f1]=f2,rank[y]=max(rank[y],rank[x]+1);
        else f[f2]=f1,rank[x]=max(rank[x],rank[y]);
    }
    return;}     

2,并查集的查询操作
就是查询两个元素是否属于同一个集合,首先我们要先找到这两个元素所在集合的特征性元素。如果两个特征性元素相同,则两个元素属于同一个集合,否则属于两个集合,其中我们用到路径压缩来优化,路径压缩就是在查询过程中,从此节点到根节点路径上的所有节点的f全部改为根节点,这样在下次查询时,就可以减少递归过程从而达到优化的目的。

inline int find(int k)
{
    if(f[k]==k) return f[k];
    return f[k]=find(f[k]);
}

*:按秩合并和路径压缩不可以同时使用,一般我们使用路径压缩来优化。


并查集完整代码(洛谷P3367)

#include<cstdio>
#include<iostream>

using namespace std;

int n,m,f[10005];

int find(int k)
{
    if(f[k]==k) return f[k];
    return f[k]=find(f[k]);
}

void merge(int x,int y)
{
    int f1=find(x);
    int f2=find(y);
    if(f1!=f2) f[f1]=f2;
    return;
} 

int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++) f[i]=i;
    for(int i=1;i<=m;i++)
    {
        int xi,yi,zi;
        scanf("%d%d%d",&zi,&xi,&yi);
        if(zi==1) merge(xi,yi);
        else if(zi==2) 
        {
            int f1=find(xi);
            int f2=find(yi);
            if(f1==f2) printf("Y\n");
            else printf("N\n");
        } 
    }
    return 0;
}

祝各位OIER NOIP2019 RP++ SCORE++

并查集

原文:https://www.cnblogs.com/Hoyoak/p/11336653.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!