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]<<'
';
        }
    }
}
原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/8403383.html