zoukankan      html  css  js  c++  java
  • 并查集按秩合并(可撤销)

    按秩合并

    并查集做成一棵树,启发式维护树高,实现(O(logn)),我们可以对节点进行一些处理,维护带权

    模板
    经典例题:(连接(u,v)),查询((u,v))什么时候联通的

    每个点有一个权值,为该子树与外部联通的时间

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    using namespace std;
    const int N = 5e5+5;
    
    int n, m, fa[N], val[N], he[N], deep[N], tim, ans;
    int find(int x) {
        if(x == fa[x]) return x;
        else {
            int f = find(fa[x]);
            deep[x] = deep[fa[x]] + 1;
            return f;
        }
    }
    void Union(int x, int y) {
        tim++;
        x = find(x); y = find(y);
        if(x == y) return;
        if(he[x] < he[y]) swap(x, y);
        fa[y] = x;
        val[y] = tim;
        he[x] = max(he[x], he[y]+1);
    }
    void Find(int x, int y) {
        int fx = find(x), fy = find(y);
        ans = 0;
        if(fx != fy) cout << ans << '
    ';
        else {
            while(x != y) {
                if(deep[x] < deep[y]) swap(x, y);
                ans = max(ans, val[x]); x = fa[x];
            }
            cout << ans << '
    ';
        }
    }
    int main() {
        freopen("in", "r", stdin);
        ios::sync_with_stdio(false); cin.tie(); cout.tie();
        cin >> n >> m;
        for(int i=1; i<=n; i++) fa[i] = i;
        for(int i=1; i<=m; i++) {
            int c, x, y;
            cin >> c >> x >> y;
            x ^= ans; y ^= ans; //printf("hi %d %d %d
    ", c, x, y);
            if(c == 0) Union(x, y);
            else Find(x, y);
        }
    }
    

    可撤销

    另一大优点是可撤销,将撤销后的影响通过栈存起来实现(换父亲,高度与子树大小)

    inline bool merge(int x, int y) {
        int fx = findf(x), fy = findf(y);
        if (fx == fy) return 0;
        if (size[fx] > size[fy]) std::swap(fx, fy);
        fa[fx] = fy;
        size[fy] += size[fx];
        stk[++top] = fx;
        return true;
    }
    

    模板

    (ZJOJ4769):判二分图就是看是否有奇环,(val[x])表示(x)与父亲的关系((1)(0)同),注意与父亲不一定相连
    (x-y),对应的(fx-fy)的关系是什么呢:

    [c[x]xor~c[y]=1,c[fx]=len[x]xor~c[x],c[fy]=len[y]xor~c[y] ]

    [c[fx]xor~c[fy]=(len[x]xor~c[x])xor~(len[y]xor~c[y])=len[x]xor~len[y]xor~1 ]

  • 相关阅读:
    hdu4665 DFS
    hdu4665 DFS
    hdu4717 三分(散点的移动)
    POJ 2559 Largest Rectangle in a Histogram(单调栈) && 单调栈
    洛谷 P2347 砝码称重
    洛谷 P3009 [USACO11JAN]利润Profits
    洛谷 P2925 [USACO08DEC]干草出售Hay For Sale
    洛谷 P1616 疯狂的采药
    洛谷 P1086 花生采摘
    洛谷 P1048 采药
  • 原文地址:https://www.cnblogs.com/y2823774827y/p/10655499.html
Copyright © 2011-2022 走看看