2023-10-07 21:26阅读: 39评论: 0推荐: 0

并查集

基本的并查集

OI-wiki Link

并查集,一种用于管理元素所属集合的数据结构,形如一片森林,同一棵树内的元素所属同一集合,不同树内的元素不属于同一集合。

将并查集拆分一下。并,合并;查,查询;集,处理的是集合相关内容。

所以并查集一共有两种操作:合并两元素对应集合、查询某元素所属集合(查询它所在树的树根)。


对于每个元素,需要记录它的父亲,用于寻找树根。

如果需要的话,可以记录它的子树大小,一般只有树根需要记录。

初始化

初始时,每个元素都是一棵树,它们自然没有父亲。

如果要记录子树大小的话,则需把它们初始都赋值为 1

查询

当我们要查询一个元素 x 所属集合时,我们需要一路往上跳,直到跳到 x 所属树的树根,这个元素也就是 x 所属的集合。

int Find (int x) { // 查询 x 所属集合
return (fa[x] ? Find(fa[x]) : x); // 如果当前节点还有父亲节点,那么就往上跳,否则返回当前节点
}

合并

假如现在要合并两个元素 x,y 的所属集合,那么只要先找到两棵树的树根,再任选一个点连向另一点即可。

如果仅仅是告诉你两个元素 x,y 所属同一集合,那么还需判断 x,y 是否所属不同集合,否则可能会导致死递归。

void merge (int x, int y) { // 合并 x, y 所属集合
x = Find(x), y = Find(y); // 找到树根
if (x != y) { // 只有 x, y 所属不同集合时才能合并
fa[x] = y; // 连接
}
}

并查集时间复杂度优化

合并的复杂度在于查询,除了查询以外只用 O(1),那么查询的复杂度呢?

很明显,我们可以利用合并构造出一种形如链状的并查集,那么在查询时复杂度仍然可以达到 O(n),并没有达到优化的效果。

那么就要提到合并和查询的优化了。

路径压缩

路径压缩,顾名思义就是把一长条路径给压缩,从而降低时间。

int Find (int x) { // 查询 x 所属集合
return (fa[x] ? fa[x] = Find(fa[x]) : x); // 如果当前节点还有父亲节点,那么就往上跳,否则返回当前节点
// 路径压缩,每次往上跳时都把 fa[x] 更新为树根。
}

启发式合并

当合并两个集合时,集合的大小会影响到后续操作,为了在一定程度上优化时间复杂度,可以选择把节点数少的集合连向节点数多的集合,也可以把深度较小的集合连向深度较大的集合。

// 按节点数启发式合并
void merge (int x, int y) { // 合并 x, y 所属集合
x = Find(x), y = Find(y); // 找到树根
if (x != y) { // 只有 x, y 所属不同集合时才能合并
if (sz[x] > sz[y]) { // 启发式合并
swap(x, y);
}
fa[x] = y, sz[y] += sz[x]; // 连接
}
}

时间复杂度比较玄学,可以自行 bdfs 或者参考 OI-wiki

一般来说路径压缩后的并查集已经不怕 T,但是启发式合并 + 路径压缩后是 O(α(n)×n),其中 α(n) 为反阿克曼函数,是一个增长十分缓慢的函数,一般题目里可以将 α(n) 视为 5 左右的一个常数,是完全不可能 T 的。

带权并查集

OI-wiki Link

就是在维护普通并查集的同时维护每个节点连接向它的父亲的边权,路径压缩时记得要更新为一段路径的边权。

例题:P1196 [NOI2002] 银河英雄传说

种类并查集

不要问我为啥没有 OI-wiki Link,因为 OI-wiki 里甚至没有这玩意。

与普通并查集十分相像,主要就是把一个元素分为几个类,可以直接开多个并查集维护。

例题:P2024 [NOI2001] 食物链

在这道题里,由于不确定每个动物的种类,则将其分类讨论,分为三类,处理时多一点细节。

本文作者:wnsyou の blog

本文链接:https://www.cnblogs.com/wnsyou-blog/p/dsu.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   wnsyou  阅读(39)  评论(0编辑  收藏  举报
  1. 1 勝利への道 安藤浩和
  2. 2 Minecraft’s End Eric Fullerton
  3. 3 月光曲完整版 贝多芬 云熙音乐
  4. 4 平凡之路 (Live版) 朴树
  5. 5 Minecraft C418
  6. 6 Paradise NiziU
  7. 7 叫我,灰原哀 龙大人不喷火
  8. 8 心机之蛙,一直摸你肚子 ——《名侦探柯南》原创同人曲 炊饭,叶辞樱,温海,寒砧,南柯柯,小茜玛姬,盛姝,阿崔Ac,贝壳初,千湛,兮茶子DaYu,乔慕,黎鹿北,起千温卿,遮阳伞,曲悠
  9. 9 战 歌 此去经年
Paradise - NiziU
00:00 / 00:00
An audio error has occurred, player will skip forward in 2 seconds.

作词 : AKIRA/Bang Chan (3RACHA)/CHANGBIN (3RACHA)/HAN (3RACHA)

作曲 : Bang Chan (3RACHA)/CHANGBIN (3RACHA)/HAN (3RACHA)/VERSACHOI

编曲 : VERSACHOI/Bang Chan(3RACHA)

昔々きいた話

ふたつの虹を超えたその向こう

光り輝く泉がある

その水面(みなも)映るのは

ほんとの自分

しあわせは今 しあわせは空

Let’s fly fly & fly We fly & fly

目と目を合わせ

信じあえるよ 感じあえるさ

Let’s fly fly & fly We fly & fly

いつか

わかるだろう

君にはもう君だけの色も形も

優しさも強さもあるんだ

上手くいかなくたって

失敗ばっかりだって

ぼくはここにいるよ

I love you so much 大好きなんだ

そのままで 大好きさ Paradise

宝物はそこにあるよ 気がついてよ

世界中探しても

君は君しかいないよ

広がる楽園 繋げよう

誰も誰もが Paradise

雨が降れば ぬかるむ道 Oh yeah

道端に咲いた花に集まる蝶を

照らす太陽は全てを温め

乾いた道に雨は降る

あたりまえだけど奇跡

小さなちっぽけな今には

大きな大きな夢が詰まっているの

悔しさに泣いたって

手を差し伸べるから

ぼくはここにいるから

I love you so much 大好きなんだ

そのままで 大好きさ Paradise

宝物は君なんだよ 気がついてよ

この惑星(ほし)の歴史にも

君は君しかいないよ

目に見えないけど確かに

ひとりひとりの Paradise

しあわせは今 しあわせは空

Let’s fly fly & fly We fly & fly

目と目を合わせ

信じあえるよ 感じあえる

だから大丈夫

心のまま行こう Paradise

加载中…

{{tag.name}}

{{tran.text}}{{tran.sub}}
无对应文字
有可能是
{{input}}
尚未录入,我来提交对应文字
评论
收藏
关注
推荐
深色
回顶
收起
点击右上角即可分享
微信分享提示