按大小划分的并集中不相交集并集路径压缩的后果

Consequences of disjoint set union path compression in union by size

提问人:David 提问时间:10/31/2023 更新时间:10/31/2023 访问量:81

问:

按大小进行并集时,可以比较尝试统一的节点的大小。 我在 codeforces 上找到了这段代码,它显示了如何构建具有路径压缩和按大小并集的 DSU:

#include <bits/stdc++.h>
using namespace std;

class DSU
{
public:
    unordered_map<int, int> parent;
    unordered_map<int, int> size;

    void make_set(int v)
    {
        parent[v] = v;
        size[v] = 1;
    }

    int find_set(int v)
    {
        if (v == parent[v])
            return v;

        return parent[v] = find_set(parent[v]);
    }

    void union_sets(int a, int b)
    {
        a = find_set(a);
        b = find_set(b);

        if (a != b)
        {
            if (size[a] < size[b])
                swap(a, b);

            // a big, b small
            // attach small tree to big tree
            parent[b] = a;
            size[a] += size[b];
        }
    }
};

问题是,您不必修改以减小父节点的大小,因为父节点现在将指向根而不是另一个子节点?find_set

这难道不是正确的实现吗?find_set

    int find_set(int v)
    {
        if (v == parent[v])
            return v;

        size[parent[v]] -= 1;
        return parent[v] = find_set(parent[v]);
    }
C++ 算法 数据结构 不相交集

评论

2赞 wohlstad 10/31/2023
旁注:(1) #include < bits/stdc++.h> (2) 使用命名空间 std
0赞 Pepijn Kramer 10/31/2023
我不知道算法(虽然我找到了这个链接。我不希望 find 方法修改任何内容。我希望它被宣布为int find_set(int v) const
0赞 n. m. could be an AI 10/31/2023
我们只关心根的大小,而不关心中间节点的大小。

答:

5赞 Darius 10/31/2023 #1

是的,但你什么也得不到,因为该父级不是集合的代表。

那是

int find_set(int v)
{
    if (v == parent[v])
        return v;
    
    // This parent is not the representative, changing
    // the size is superfluous as it will no longer 
    // be referenced again.
    size[parent[v]] -= 1;
    return parent[v] = find_set(parent[v]);
}

评论

0赞 Matt Timmermans 11/1/2023
而且,由于您永远不需要大小和链接,因此您只需要一个数组:stackoverflow.com/questions/60004277/...