zoukankan      html  css  js  c++  java
  • bzoj2816: [ZJOI2012]网络

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

    每种颜色搞一个LCT

    判断u v之间有边直接相连:

    如果u和v之间有边相连,那么他们的深度相差1

    所以

    make_root(u);

    access(v);

    splay(v);

    判断u的父亲是不是v 以及 u是不是没有右儿子

    #include<cstdio>
    #include<iostream>
    
    using namespace std;
    
    #define N 10001
    
    void read(int &x)
    {
        x=0; char c=getchar();
        while(!isdigit(c)) c=getchar();
        while(isdigit(c)) { x=x*10+c-'0'; c=getchar(); }
    }
    
    struct LCT
    {
        int ch[N][2],fa[N];
        int key[N],mx[N];
        int d[N];
        
        bool rev[N];
        
        int st[N],top;
        
        void update(int x)
        {
            mx[x]=key[x];
            mx[x]=max(mx[x],mx[ch[x][0]]);
            mx[x]=max(mx[x],mx[ch[x][1]]);
        }
        
        void down(int x)
        {
            if(rev[x])
            {
                rev[x]^=1;
                swap(ch[x][0],ch[x][1]);
                rev[ch[x][0]]^=1;
                rev[ch[x][1]]^=1;
            }
        }
        
        bool getson(int x)
        {
            return ch[fa[x]][1]==x;
        }
        
        bool isroot(int x)
        {
            return ch[fa[x]][0]!=x && ch[fa[x]][1]!=x;
        }
        
        void rotate(int x)
        {
            int y=fa[x],z=fa[y];
            bool k=ch[y][1]==x;
            if(!isroot(y)) ch[z][ch[z][1]==y]=x;
            ch[y][k]=ch[x][k^1]; ch[x][k^1]=y;
            fa[y]=x; fa[x]=z; fa[ch[y][k]]=y;
            update(y);
        }
        
        void splay(int x)
        {
            st[top=1]=x;
            for(int i=x;!isroot(i);i=fa[i]) 
            st[++top]=fa[i];
            for(int i=top;i;--i) down(st[i]);
            int y;
            while(!isroot(x))
            {
                y=fa[x];
                if(!isroot(y)) rotate(getson(x)==getson(y) ? y : x);
                rotate(x);
            }
            update(x);
        }
        
        void access(int x)
        {
            int t=0;
            while(x)
            {
                splay(x);
                ch[x][1]=t;
                update(x);
                t=x; x=fa[x];
            }
        }
        
        void make_root(int x)
        {
            access(x);
            splay(x);
            rev[x]^=1;
        }
        
        void link(int x,int y)
        {
            make_root(x);
            fa[x]=y;
            d[x]++; d[y]++;
            splay(x);
        }
        
        void cut(int x,int y)
        {
            make_root(x);
            access(y);
            splay(y);
            ch[y][0]=fa[x]=0;
            update(y);
            d[x]--; d[y]--;
        }
        
        int findroot(int x)
        {
            access(x);
            splay(x);
            while(ch[x][0]) x=ch[x][0];
            return x;
        }
        
        bool query(int x,int y)
        {
            int a=findroot(x);
            int b=findroot(y);
            return a==b;
        }
        
        bool query_edge(int u,int v)
        {
            make_root(u);
            access(v);
            splay(v);
            return fa[u]==v && !ch[u][1];
        }
            
    }Lct[10];
    
    int main()
    {
        freopen("networkzj.in","r",stdin);
        freopen("networkzj.out","w",stdout);
        int n,m,c,q;
        read(n); read(m); read(c); read(q);
        int u,v,w,k;
        for(int i=1;i<=n;++i)
        {
            read(w);
            for(int j=0;j<c;++j) Lct[j].key[i]=Lct[j].key[i]=w;
        }
        while(m--)
        {
            read(u); read(v); read(w);
            Lct[w].link(u,v);
        }
        while(q--)
        {
            read(k);
            if(!k)
            {
                read(u); read(w);
                for(int i=0;i<c;++i) 
                {
                    Lct[i].make_root(u);
                    Lct[i].key[u]=w;
                    Lct[i].update(u);
                }
            }
            else if(k==1)
            {
                read(u); read(v); read(w);
                int i;
                for(i=0;i<c;++i)
                    if(Lct[i].query_edge(u,v) ) break;
                if(i==c) { puts("No such edge."); continue; }
                if(i==w) { puts("Success."); continue; }
                if(Lct[w].d[u]==2 || Lct[w].d[v]==2) { puts("Error 1."); continue; }
                if(Lct[w].query(u,v)) { puts("Error 2."); continue; }
                Lct[i].cut(u,v);
                Lct[w].link(u,v);
                puts("Success.");
            }
            else
            {
                read(w); read(u); read(v);
                if(!Lct[w].query(u,v)) { puts("-1"); continue; }
                Lct[w].make_root(u);
                Lct[w].access(v);
                Lct[w].splay(v);
                cout<<Lct[w].mx[v]<<'
    ';
            }
        }
    }
  • 相关阅读:
    opencv实现连通域
    C Tips:显示点阵汉字的小样例
    协方差的意义
    HashTable类模板_C++
    Java实现 蓝桥杯VIP 算法提高 选择排序
    Java实现 蓝桥杯VIP 算法提高 笨小猴
    Java实现 蓝桥杯VIP 算法提高 笨小猴
    Java实现 蓝桥杯VIP 算法提高 笨小猴
    Java实现 蓝桥杯VIP 算法提高 笨小猴
    Java实现 蓝桥杯VIP 算法提高 笨小猴
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/8403383.html
Copyright © 2011-2022 走看看