UDSU-可撤销并查集


因为要支持撤销操作, 所以没法路径压缩, 只能按秩合并, 这里的秩为深度.

用一个栈来记录每次 bind 操作之前的状态, undo 的时候直接从栈中取即可.

class UDSU {
public:
    std::vector<int> f, size;
    std::stack<std::array<int, 2>> sta;
    UDSU(std::size_t size) : f(size + 1), size(size + 1) {
        std::iota(f.begin(), f.end(), 0);
    }
    int root(int u) {
        return f[u] == u ? u : root(f[u]);
    }
    void bind(int u, int v) {
        u = root(u), v = root(v);
        if (size[u] > size[v])
            std::swap(u, v);
        sta.push({u, size[v]});
        f[u] = v;
        if (size[u] == size[v])
            size[v]++;
    }
    void undo() {
        auto [u, sizev] = sta.top();
        sta.pop();
        size[f[u]] = sizev, f[u] = u;
    }
};
,

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注