并查集

并查集动态维护多个不重复集合,每个集合有代表元素。初始化时每个元素单独成集,查询通过递归找代表元素。

路径压缩在查询时直接更新父节点指向代表元素,避免退化链。合并操作将两个集合的代表元素相连。

并查集是一种动态维护多个不重复集合

在并查集中,每个集合都有自己的代表元素。

一个树 $ fa $ 记录每一个元素的归属关系(存储所属集合代表元素的下标)。

具体:

初始状态:

即,每个元素都是一个单独的集合

int fa[mxn];
for (int i = 0; i < n; i++) fa[i] = i;

常见操作

Get

查询一个元素属于哪一个集合(通常题目中会问两个元素是否属于同一集合)

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

(查询某元素所属集合的代表元素)

那么请考虑这样一种情况:

它退化成了一条链!这样时间复杂度就会大大增加!那么假如元素直接指向代表元素,那假如代表元素迁移(见后)了呢?就在find时实时更新呗!

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

仔细观察代码你会发现只添加了 fa[x]= 这几个字。这就是路径压缩

(有点像记忆化搜索?

查询两个元素是否属于同一集合的代码也很简单

bool is_in_one_set(int b, int c){
    return find(b) == find(c);
}

Merge

把两个元素 $ a $、$ b $ 所在的集合合并为一个

随意修改 $ a $、$ b $ 中一个的父元素为另一个的父元素

void merge(int a, int b) {
    int fa_ = find(a);
    int fb = find(b);
    fa[fa_] = fb;
}
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇