可删除并查集 - myf并查集

继月赛出了道可删除并查集后,又做了几道可删除并查集的题,发现之前的代码有点小问题。

可删除并查集的基本原理是设置一个虚点,也就是说一个点删除了,那么他对应的值就不再是之前的那一个点,而是变成了其他点。

即可删除并查集通过id映射的关系查找我的点在哪里。

有几个问题就是初始化时必须要把\(n + m\)个点的父亲结点都设置为本身,(n是点个数,m是操作次数)
然后关于查询父亲结点的操作,必须通过id去映射。

对于删去的点,其实原来的点还是存在的。如果说2的父亲是1,且1被删除,那么查询2的父亲返回的是1,查询2的父亲,返回的是n+第几次操作。
但是不影响。主要是我想去查找这个点的真正父亲结点到底是哪个不太行。

模板

struct DSU{
    int fa[N << 1], rnk[N << 1], id[N << 1], tot;
    int find_(int x){ // 其他地方访问find都要用find(id[x])
        return x == fa[x] ? x : fa[x] = find_(fa[x]);
    }
    int find(int x) { // 查询x的父亲结点
        return find_(id[x]);
    }
    void move(int x){ // 把点x从集合里删除
        int fx = find(x);
        rnk[fx]--;
        id[x] = ++tot;
    }
    void init(int n, int m){
        tot = n;
        for(int i = 1; i <= n + m; i++) fa[i] = id[i] = i, rnk[i] = 1;
    }
    void unit(int x, int y){ // 合并x和y
        int fx = find(x), fy = find(y);
        if(fx != fy) {
            fa[fx] = fy;
            rnk[fy] += rnk[fx];
        }
    }
} dsu;

传送门
传送门
传送门

posted @ 2021-01-31 18:59  Emcikem  阅读(258)  评论(0编辑  收藏  举报