洛谷P2173/BZOJ2816[ZJOI2012]网络

如果$c=0$(也就是只有一种颜色),那么开一个LCT,再维护一下结点度即可;那么现在$c<10$,考虑开$c+1$棵LCT,一起维护。边查找直接上map就可以了。

#include<cstdio>
#include<map>
using namespace std;
const int N=10005;
char rB[1<<21],*rS,*rT;
inline char gc(){return rS==rT&&(rT=(rS=rB)+fread(rB,1,1<<21,stdin),rS==rT)?EOF:*rS++;}
inline int rd(){
    char c=gc();
    while(c<48||c>57)c=gc();
    int x=c&15;
    for(c=gc();c>=48&&c<=57;c=gc())x=(x<<3)+(x<<1)+(c&15);
    return x;
}
int val[N],st[N],sl;
struct edge{
    int u,v;
    edge(){}
    edge(int x,int y){
        if(x<y){u=x;v=y;}
        else{u=y;v=x;}
    }
    inline bool operator <(const edge &b)const{return u<b.u||u==b.u&&v<b.v;}
};
map<edge,int> f;
struct LCT{
    int maxn[N],f[N],ch[N][2],d[N];
    bool tag[N];
    inline bool nrt(int o){return ch[f[o]][0]==o||ch[f[o]][1]==o;}
    inline bool dir(int o){return ch[f[o]][1]==o;}
    inline void flip(int o){
        if(o){
            int t=ch[o][0];ch[o][0]=ch[o][1];ch[o][1]=t;
            tag[o]^=1;
        }
    }
    inline void pushup(int o){
        maxn[o]=maxn[ch[o][0]]>maxn[ch[o][1]]?maxn[ch[o][0]]:maxn[ch[o][1]];
        if(val[o]>maxn[o])maxn[o]=val[o];
    }
    inline void pushd(int o){
        if(tag[o]){
            flip(ch[o][0]);flip(ch[o][1]);
            tag[o]=0;
        }
    }
    inline void rot(int o){
        int fa=f[o];
        bool d=dir(o);
        f[o]=f[fa];
        if(nrt(fa))ch[f[fa]][dir(fa)]=o;
        if(ch[fa][d]=ch[o][d^1])f[ch[fa][d]]=fa;
        f[ch[o][d^1]=fa]=o;
        pushup(fa);
    }
    inline void splay(int o){
        int k=st[sl=0]=o;
        while(nrt(k)){k=f[k];st[++sl]=k;}
        while(sl>=0)pushd(st[sl--]);
        for(;nrt(o);rot(o))if(nrt(f[o]))rot((dir(o)^dir(f[o]))?o:f[o]);
        pushup(o);
    }
    inline void access(int x){
        for(int y=0;x;x=f[y=x]){
            splay(x);
            ch[x][1]=y;
            pushup(x);
        }
    }
    inline int findrt(int x){
        access(x);splay(x);
        for(pushd(x);ch[x][0];pushd(x))x=ch[x][0];
        splay(x);
        return x;
    }
    inline void makert(int x){
        access(x);splay(x);
        flip(x);
    }
    inline void link(int x,int y){
        makert(x);
        ++d[x];++d[y];
        f[x]=y;
    }
    inline void cut(int x,int y){
        makert(x);access(y);splay(x);
        --d[x];--d[y];
        ch[x][1]=f[y]=0;
        pushup(x);
    }
}lct[10];
int main(){
    int n=rd(),m=rd(),c=rd(),q=rd(),i,j,u,v,w,p,opt;
    for(i=1;i<=n;++i){
        val[i]=rd();
        for(j=0;j<c;++j)lct[j].maxn[i]=val[i];
    }
    while(m--){
        u=rd();v=rd();w=rd();
        lct[w].link(u,v);
        f[edge(u,v)]=w;
    }
    while(q--){
        opt=rd();u=rd();v=rd();
        if(!opt){
            val[u]=v;
            for(i=0;i<c;++i)lct[i].splay(u);
        }else if(opt==1){
            w=rd();
            if(f.find(edge(u,v))==f.end()){puts("No such edge.");continue;}  //用find或者count,不要用[]
            p=f[edge(u,v)];
            if(w==p){puts("Success.");continue;}
            if(lct[w].d[u]>=2||lct[w].d[v]>=2){puts("Error 1.");continue;}
            lct[w].makert(u);
            if(lct[w].findrt(v)==u){puts("Error 2.");continue;}
            puts("Success.");
            lct[p].cut(u,v);lct[w].link(u,v);
            f[edge(u,v)]=w;
        }else if(opt==2){
            lct[u].makert(v);
            if(lct[u].findrt(w=rd())!=v)puts("-1");
            else printf("%d\n",lct[u].maxn[v]);
        }
    }
    return 0;
}
View Code

猜你喜欢

转载自www.cnblogs.com/sunshine-chen/p/11294548.html