zoukankan      html  css  js  c++  java
  • [ZJOI 2012] 网络

    [题目链接]

               https://www.lydsy.com/JudgeOnline/problem.php?id=2816

    [算法]

             对每种颜色的边建一棵LCT , 维护联通性即可

             时间复杂度 : O(C * NlogN ^ 2)

    [代码]

              

    #include<bits/stdc++.h>
    using namespace std;
    const int MAXN = 2e5 + 10;
    const int MAXC = 15;
    typedef long long ll;
    typedef long double ld;
    typedef unsigned long long ull;
    
    int n , m , c , k;
    int u[MAXN] , v[MAXN] , w[MAXN] , val[MAXN] , cnt[MAXC][MAXN];
    map< pair<int , int> , int> mp;
    
    template <typename T> inline void chkmax(T &x,T y) { x = max(x,y); }
    template <typename T> inline void chkmin(T &x,T y) { x = min(x,y); }
    template <typename T> inline void read(T &x)
    {
        T f = 1; x = 0;
        char c = getchar();
        for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
        for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0';
        x *= f;
    }
    
    struct Link_Cut_Tree
    {
            struct Node
            {
                    int father , son[2] , value , mx;
                    bool tag;        
            }    a[MAXN];
            inline void init()
            {
                    for (int i = 1; i <= n; i++)
                    {
                            a[i].father = 0;
                            a[i].son[0] = a[i].son[1] = 0;
                            a[i].value = a[i].mx = val[i];
                            a[i].tag = false;
                    }
            }
            inline void pushdown(int x)
            {
                    if (a[x].tag)
                    {
                            swap(a[x].son[0] , a[x].son[1]);
                            a[a[x].son[0]].tag ^= 1;
                            a[a[x].son[1]].tag ^= 1;
                            a[x].tag = false;
                    }
            }
            inline void update(int x)
            {
                    a[x].mx = a[x].value;
                    if (a[x].son[0]) chkmax(a[x].mx , a[a[x].son[0]].mx);
                    if (a[x].son[1]) chkmax(a[x].mx , a[a[x].son[1]].mx);
            }
            inline bool get(int x)
            {
                    pushdown(x);
                    return a[a[x].father].son[1] == x;
            }
            inline bool nroot(int x)
            {
                    return a[a[x].father].son[0] == x || a[a[x].father].son[1] == x;
            }
            inline void rotate(int x)
            {
                    int f = a[x].father , g = a[f].father;
                    int tmpx = get(x) , tmpf = get(f);
                    int w = a[x].son[tmpx ^ 1];
                    if (nroot(f)) a[g].son[tmpf] = x;
                    a[x].son[tmpx ^ 1] = f;
                    a[f].son[tmpx] = w;
                    if (w) a[w].father = f;
                    a[f].father = x;
                    a[x].father = g;
                    update(f);
            }
            inline void splay(int x)
            {
                    int y = x , z = 0;
                    static int st[MAXN];
                    st[++z] = y;
                    while (nroot(y)) st[++z] = y = a[y].father;
                    while (z) pushdown(st[z--]);
                    while (nroot(x))
                    {
                            int y = a[x].father , z = a[y].father;
                            if (nroot(y))
                                    rotate((a[z].son[0] == y) ^ (a[y].son[0] == x) ? x : y);
                            rotate(x);
                    }
                    update(x);
            }
            inline void access(int x)
            {
                    for (int y = 0; x; x = a[y = x].father)
                    {
                            splay(x);
                            a[x].son[1] = y;
                            update(x);
                    }
            }
            inline void make_root(int x)
            {
                    access(x);
                    splay(x);
                    a[x].tag ^= 1;
                    pushdown(x);
            }
            inline void link(int x , int y)
            {
                    make_root(x);
                    if (find_root(y) != x) a[x].father = y;
            }
            inline int find_root(int x)
            {
                    access(x);
                    splay(x);
                    while (a[x].son[0])
                    {
                            pushdown(x);
                            x = a[x].son[0];
                    }
                    return x;
            }
            inline void cut(int x , int y)
            {
                    make_root(x);
                    if (find_root(y) == x && a[x].father == y && !a[x].son[1])
                    {
                            a[x].father = a[y].son[0] = 0;
                            update(y);
                    }
            }
            inline void split(int x , int y)
            {
                    make_root(x);
                    access(y);
                    splay(y);
            }
            inline void modify(int x , int y)
            {
                    splay(x);
                    a[x].value = y;
                    update(x);
            }
            inline bool connected(int x , int y)
            {
                    return (find_root(x) == find_root(y));
            }
            inline int query(int x , int y)
            {
                    split(x , y);
                    return a[y].mx;
            }
    } T[MAXC];
    
    int main()
    {
            
            read(n); read(m); read(c); read(k);
            for (int i = 1; i <= n; i++) read(val[i]);
            for (int i = 0; i < c; i++) T[i].init(); 
            for (int i = 1; i <= m; i++)
            {
                    read(u[i]); read(v[i]); read(w[i]);
                    mp[make_pair(u[i] , v[i])] = mp[make_pair(v[i] , u[i])] = w[i];
                    T[w[i]].link(u[i] , v[i]);    
                    ++cnt[w[i]][u[i]]; ++cnt[w[i]][v[i]];
            } 
            for (int i = 1; i <= k; i++)
            {
                    int type;
                    read(type);
                    if (type == 0)
                    {
                            int x , y;
                            read(x); read(y);
                            for (int i = 0; i < c; i++) T[i].modify(x , y);        
                    }    else if (type == 1)
                    {
                            int u , v , w;
                            read(u); read(v); read(w);
                            if (!mp.count(make_pair(u , v))) 
                            {
                                    printf("No such edge.
    ");
                                    continue;
                            } else
                            {
                                    int value = mp[make_pair(u , v)];
                                    if (value == w) 
                                    {
                                            printf("Success.
    ");
                                            continue;
                                    }
                                    if (cnt[w][u] >= 2 || cnt[w][v] >= 2)
                                    {
                                            printf("Error 1.
    ");
                                            continue;
                                    }
                                    if (T[w].connected(u , v))
                                    {
                                            printf("Error 2.
    ");
                                            continue;
                                    }
                                    printf("Success.
    ");
                                    T[value].cut(u , v);
                                    --cnt[value][u]; --cnt[value][v];
                                    T[w].link(u , v);
                                    mp[make_pair(u , v)] = mp[make_pair(v , u)] = w;
                                    ++cnt[w][u]; ++cnt[w][v];
                            } 
                    } else
                    {
                            int w , u , v;
                            read(w); read(u); read(v);
                            if (!T[w].connected(u , v)) printf("-1
    ");
                            else printf("%d
    " , T[w].query(u , v));
                    }
            }
            
            return 0;
        
    }
  • 相关阅读:
    前端历险记
    Pandas中空值的判断方法,包括数值型、字符串型、时间类型等
    【MySQL】explicit_defaults_for_timestamp 参数详解
    python并发编程--线程---从菜鸟到老鸟(一)
    远程jupyter+pycharm配置 (一)之安装与使用技巧
    airflow--Error: Already running on PID 22603 (or pid file '/home/rdev/airflow/airflow-webserver.pid' is stale)
    数仓调度研究-总论
    pandas实现hive的lag和lead函数 以及 first_value和last_value函数
    iOS开发小技巧--修改按钮内部图片和文字之间的间距(xib)
    iOS开发中的错误整理,关于用绑定Tag取控件的注意事项,有时候不绑定也是个错!
  • 原文地址:https://www.cnblogs.com/evenbao/p/10159318.html
Copyright © 2011-2022 走看看