并查集模板

并查集介绍

并查集是一种树形结构,常用于解决不相交集合的查询与合并问题,典型应用如 Kruskal 最小生成树算法。

要点

核心API:

  • connected:判断两个节点是否属于同一个集合(是否连通);
  • unionNodes:将两个节点划分到同一个集合中(连通)。

实现时,通常使用parent数组记录每个节点的父节点,当前森林中的连通分量数则用全局的count表示,在unionNodes时动态维护。

此外,为防止出现树退化成链表的极端情况,需要路径压缩(或平衡性优化)来保证树的高度为常量。采用路径压缩的技巧后,除初始化外,其余操作的平均复杂度均为 O(1)。

代码模板

class UF
{
private:
	/* 连通分量数 */
    int count;
    /* 每个节点的父节点 */
    int *parent; 

public:
    UF(int n)
    {
        count = n;
        parent = new int[n];
        for (int i = 0; i < n; i++)
            parent[i] = i;
    }

    ~UF()
    {
        delete[] parent;
    }

    void unionNodes(int u, int v)
    {
        int root_u = find(u);
        int root_v = find(v);
        if (root_u == root_v)
            return;
        parent[root_u] = root_v;
        count--;
    }

    /* 路径压缩,返回根节点 */
    int find(int u)
    {
        if (parent[u] != u)
        {
            parent[u] = find(parent[u]);
        }
        return parent[u];
    }

    bool connected(int u, int v)
    {
        return find(u) == find(v);
    }

    int getCount()
    {
        return count;
    }
};

练习

Tips

  • 网格图中,可能需要使用虚拟的哑节点简化实现过程;
  • 二维坐标 (x, y) 映射到一维的 x * n + y(n为列数),方便套用以上模板;
  • 作为一种技巧性的数据结构,大部分可使用并查集的题目直接DFS即可。

Leetcode相关题目

  1. leetcode 130. 被围绕的区域
  2. leetcode 765. 情侣牵手(困难题)
  3. leetcode 990. 等式方程的可满足性

参考

[1] https://labuladong.github.io/algo/di-yi-zhan-da78c/shou-ba-sh-03a72/bing-cha-j-323f3/
[2] https://labuladong.github.io/algo/di-yi-zhan-da78c/shou-ba-sh-03a72/kruskal-zu-e6b5b/

  • 10
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值