并查集

什么是并查集

并查集是一种用于管理元素所属集合的数据结构,实现为一个森林,其中每棵树表示一个集合,树中的节点表示对应集合中的元素。

——摘自oiwiki

简单来说,并查集是一种可以快速求出一个元素的祖先的数据结构

并查集的初始化

通常,我们将每个节点的 $f_i$ 设为自己,即 $i$。

for(int i=1;i<=n;i++) f[i]=i;

并查集的查询(普通)

通过不断递归来查找元素所在的根

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

这种情况下,如果树的高度很大,那么单次查询的时间复杂度为 $O(n)$

并查集的查询(路径压缩)

每次查询之后直接将此节点接在集合代表节点的下方,以后的查询就是 $O(1)$ 的了。均摊时间复杂度为 $O(\log n)$

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

并查集的合并

可以理解为将一个并查集接在另一个并查集的根节点上

void move(int x,int y){
    int fx=find(x),fy=find(y);
    if(fx!=fy){
        f[fx]=fy;
    }
}

带权并查集

即边权带值的并查集。

即一个并查集在合并,查询的过程中还需要维护边权上的权值总和。

例题:

P1196 银河英雄传说

P1525 关押罪犯

P5092 方块游戏

posted @ 2023-04-26 21:33  固态H2O  阅读(1)  评论(0编辑  收藏  举报  来源