嘉嘉
A person
嘉嘉的博客

并查集

AI Summary

并查集是一种动态管理不重复集合的数据结构,通过代表元素和路径压缩优化查找效率,支持合并操作,将两个元素所在的集合合并成一个。具有快速查询元素所属集合和合并集合的特点,广泛应用于图的连通性问题等场景。

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

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

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

具体:

初始状态:

/wp-content/uploads/old_images/5a65.png

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

int fa[mxn];
for (int i = 0; i < n; i++) fa[i] = i;Code language: C++ (cpp)

常见操作

Get

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

int find(int x) {
    if (fa[x] == x) return x;
    return find(fa[x]);
}Code language: C++ (cpp)

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

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

/wp-content/uploads/old_images/c843.png

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

/wp-content/uploads/old_images/f58e.png

int find(int x) {
    if (fa[x] == x) return x;
    return fa[x] = find(fa[x]);
}Code language: C++ (cpp)

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

(有点像记忆化搜索?

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

bool is_in_one_set(int b, int c){
    return find(b) == find(c);
}Code language: C++ (cpp)

Merge

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

/wp-content/uploads/old_images/0a13.png

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

void merge(int a, int b) {
    int fa_ = find(a);
    int fb = find(b);
    fa[fa_] = fb;
}
Code language: C++ (cpp)
justin的头像

justin

Author

Leave a Reply

textsms
account_circle
email

嘉嘉的博客

并查集
并查集是一种动态维护多个不重复集合 在并查集中,每个集合都有自己的代表元素。 一个树 $ fa $ 记录每一个元素的归属关系(存储所属集合代表元素的下标)。 具体: 初始状态: 即,每个元素都是一个单独的集合 常见操作 Get 查询一个元素属于哪一个集合(通常题目中会问两个元素是否属于同一集合) (查询某元素所属集合的代表元素) 那么请考虑这样一种情况: 它退化成了一条链!这样时间复杂度就会大大增加!那么假如元素直接指向代表元素,那假如代表元素迁移(见后)了呢?就在find时实时更新呗! 仔细观察代码你会发现只添加了 fa[x]= 这几个字。这就是路径压缩 (有点像记忆化搜索? 查询两个元素是否属于同一集合的代码也很简单 Merge 把两个元素 $ a $、$ b $ 所在的集合合并为一个 随意修改 $ a $、$ b $ 中一个的父元素为另一个的父元素
Scan QR code to continue reading
2023-01-18