可撤销并查集模板

struct UFS {
    stack<pair<int*, int> > stk;
    int fa[maxn], rnk[maxn];
    inline void init(int n) {
        for (int i = 0; i <= n; ++i) fa[i] = i, rnk[i] = 0;
    }
    inline int find(int x) {
        while(x^fa[x]) x = fa[x];
        return x;
    }
    inline void unite(int x, int y) {
        x = find(x), y = find(y);
        if(x == y) return ;
        if(rnk[x] <= rnk[y]) {//先连边,再修改rank,撤销的时候就会最后撤销边
            stk.push({fa+x, fa[x]});
            fa[x] = y;
            if(rnk[x] == rnk[y]) {
                stk.push({rnk+y, rnk[y]});
                rnk[y]++;
            }
        }
        else {
            stk.push({fa+y, fa[y]});
            fa[y] = x;
        }
    }
    inline void undo() {
        *stk.top().first = stk.top().second;
        stk.pop();
    }
}ufs;
posted @ 2020-11-29 12:35  UCPRER  阅读(103)  评论(0编辑  收藏  举报