• 并查集按秩合并(可撤销)


    按秩合并

    并查集做成一棵树,启发式维护树高,实现(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 ]

  • 相关阅读:
    hdu 2106 decimal system
    00-自测4. Have Fun with Numbers (20)
    07-图4. Saving James Bond
    hdu 2209 翻纸牌游戏
    hdu 1272 小希的迷宫
    1969 Pie
    怎样维护 SQLite
    Navicat使用亮点
    Navicat for MySQL 11 Mac安装教程
    Navicat for PostgreSQL 运算符有哪些类别
  • 原文地址:https://www.cnblogs.com/y2823774827y/p/10655499.html
Copyright © 2020-2023  润新知