Union Find :解决集合 合并O(1)、查找O(1)

原生操作:

  • 查询量元素是否在同一集合
  • 合并两元素所在集合

派生操作:

  • 查询某个元素所在集合的元素个数
  • 查询当前集合个数

模板:

class UnionFind {
public:
    UnionFind(int n) {
        father = vector<int>(n, 0);  // father为自己表示为0
    }
    int find(int x) {
        if (father[x] == 0) {  
            return x;
        }
        return father[x] = find(father[x]);  // compressed unionfind压缩路径
    }

    void union(int a, int b) {
        int root_a = find(a);
        int root_b = find(b);
        if (root_a != root_b) {
            father[root_a] = root_b;  // union一定是在能代表整个集合的“老大哥”节点进行,而不是ab本身,
        }                             // 这样才能代表整个集合的合并
    }

    bool inTheSameUnion(int a, int b) {  // 通过判断“老大哥”是否相等来判断是否在同一集合
        return find(a) == find(b);       // 不能直接用father[]判断,因为要通过find压缩路径才能得到最新的“老大哥”
    }

private:
    vector<int> father;
}

results matching ""

    No results matching ""