zoukankan      html  css  js  c++  java
  • luoguP2173 [ZJOI2012]网络 LCT

    链接

    luogu

    思路

    颜色很少,开10个lct分别维护

    if (Hash.count(make_pair(u, v)) && Hash[make_pair(u, v)] == col) {puts("Success.");continue;}
    

    这一行的代码调了半天。

    代码

    #include <bits/stdc++.h>
    #define ls c[x][0]
    #define rs c[x][1]
    using namespace std;
    const int N = 5e4 + 7;
    int read() {
        int x = 0, f = 1; char s = getchar();
        for (;s > '9' || s < '0'; s = getchar()) if (s == '-') f = -1;
        for (;s >= '0' && s <= '9'; s = getchar()) x = x * 10 + s - '0';
        return x * f;        
    }
    map<pair<int, int>, int> Hash;
    int n, m, c, k, w[N];
    struct LCT {
        int ru[N];
        int f[N], c[N][2], ma[N], stak[N], lazy[N];
        bool isroot(int x) {return c[f[x]][0] == x || c[f[x]][1] == x;}
        void pushup(int x) {ma[x] = max(max(ma[ls], ma[rs]), w[x]);}
        void tag(int x){swap(ls,rs), lazy[x] ^= 1;}
        void pushdown(int x) {
            if (lazy[x]) {
                if (ls) tag(ls);
                if (rs) tag(rs);
                lazy[x] ^= 1;
            }
        }
        void rotate(int x) {
            int y = f[x], z = f[y], k = c[y][1] == x, w = c[x][!k];
            if (isroot(y)) c[z][c[z][1] == y] = x;
            c[x][!k] = y;
            c[y][k] = w;
            if (w) f[w] = y;
            f[x] = z;
            f[y] = x;
            pushup(y);
        }
        void splay(int x) {
            int y = x, z = 0;
            stak[++z] = y;
            while (isroot(y)) stak[++z] = y = f[y];
            while (z) pushdown(stak[z--]);
            while (isroot(x)) {
                y = f[x], z = f[y];
                if (isroot(y)) rotate((c[y][0] == x)^(c[z][0] == y) ? x : y);
                rotate(x);
            }
            pushup(x);
        }
        void access(int x) {
            for (int y = 0; x;x = f[y = x])
                splay(x), rs = y, pushup(x);
        }
        void makeroot(int x) {
            access(x), splay(x);
            tag(x);
        }
        int findroot(int x) {
            access(x), splay(x);
            while(ls) pushdown(x), x = ls;
            return x;
        }
        void split(int x, int y) {
            makeroot(x), access(y), splay(y);
        }
        void link(int x, int y) {
            makeroot(x);
            if (findroot(y) != x) f[x] = y;
        }
        void cut(int x, int y) {
            makeroot(x);
            if (findroot(y) == x && f[x] == y && !rs) {
                f[x] = c[y][0] = 0;
                pushup(y);
            }
        }
    }lct[11];
    int main() {
        // freopen("a.in", "r", stdin);
        int n = read(), m = read(), c = read(), k = read();
        for (int i = 1; i <= n; ++i) w[i] = read();
        for (int i = 1; i <= m; ++i) {
            int u = read(), v = read(), col = read();
            Hash[make_pair(u, v)] = col;
            Hash[make_pair(v, u)] = col;
            lct[col].link(u, v);
            lct[col].ru[u]++,lct[col].ru[v]++;
        }
        for (int i = 1; i <= k; ++i) {
            int opt = read();
            if (opt == 0) {
                int x = read(), y = read();
                w[x] = y;
                for (int j = 0; j <= c; ++j) 
                    lct[j].splay(x),lct[j].pushup(x);
            } else if (opt == 1) {
                int u = read(), v = read(), col = read();
                if (Hash.count(make_pair(u, v)) && Hash[make_pair(u, v)] == col) {puts("Success.");continue;}
                if (!Hash.count(make_pair(u, v))) {puts("No such edge.");continue;}
                if (lct[col].ru[u] >= 2 || lct[col].ru[v] >= 2) {puts("Error 1.");continue;}
                if (lct[col].findroot(u) == lct[col].findroot(v)) {puts("Error 2.");continue;}
                int old_col = Hash[make_pair(u,v)];
                Hash[make_pair(u, v)] = Hash[make_pair(v, u)] = col;
                lct[old_col].ru[u]--, lct[old_col].ru[v]--;
                lct[col].ru[u]++, lct[col].ru[v]++;
                lct[old_col].cut(u, v);
                lct[col].link(u, v);
                puts("Success.");
            } else {
                int col = read(), u = read(), v = read();
                if (lct[col].findroot(u) == lct[col].findroot(v)) {
                    lct[col].split(u, v);
                    printf("%d
    ", lct[col].ma[v]);
                } else puts("-1");
            }
        }
        return 0;
    }
    
  • 相关阅读:
    神文章2:文本矩阵简述 V1.0 -vivo神人
    收集:经典语录收集
    java 实现唯一ID生成器
    Mybatis-Generator自动生成XML文件以及接口和实体类
    form表单提交,Servlet接收并读取Excel文件
    海南小地图(echart)
    Echart 仪表盘和柱形图
    微信小程序图片上传并展示
    springMvc基于注解登录拦截器
    这是一个定时脚本,主要功能是遍历该文件夹下的所有文件并存储到数组,对数据中的文件进行操作,一个一个移动到指定的目录下,并删除原有文件
  • 原文地址:https://www.cnblogs.com/dsrdsr/p/10960877.html
Copyright © 2011-2022 走看看