网络

思路显然,就是对每一个颜色建一棵LCT(有没有想过颜色多了怎么办

讲一讲我从这道题里面get到的小技能。

判断连通性:

if(findroot(x)==findroot(y))return true;
else return false;

还有一个比较坑的地方就是它修改颜色的时候可能跟以前相同,这里要特判。

看代码:

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e4+10;
int n,m,col,q,val[maxn];
struct LCT{
    int p[maxn],f[maxn],c[maxn][5],mx[maxn],rev[maxn];
    inline void pushup(int x){
        mx[x]=max(val[x],max(mx[c[x][0]],mx[c[x][1]]));
    }
    inline void pushr(int x){
        swap(c[x][0],c[x][1]);
        rev[x]^=1;
    }
    inline void pushdown(int x){
        if(rev[x]){
            if(c[x][0])pushr(c[x][0]);
            if(c[x][1])pushr(c[x][1]);
            rev[x]=0;
        }
    }
    inline int nroot(int x){
        return c[f[x]][0]==x||c[f[x]][1]==x;
    }
    inline void pushall(int x){
        if(nroot(x))pushall(f[x]);
        pushdown(x);
    }
    inline void rotate(int x){
        int y=f[x],z=f[y],k=(c[y][1]==x),w=c[x][!k];
        if(nroot(y))c[z][(c[z][1]==y)]=x;c[x][!k]=y;c[y][k]=w;
        if(w)f[w]=y;f[y]=x;f[x]=z;
        pushup(y);
    }
    inline void splay(int x){
        pushall(x);
        while(nroot(x)){
            int y=f[x],z=f[y];
            if(nroot(y))rotate((c[y][0]==x)^(c[z][0]==y)?x:y);
            rotate(x);
        }
        pushup(x);
    }
    inline void access(int x){
        for(int y=0;x;y=x,x=f[x])
            splay(x),c[x][1]=y,pushup(x);
    }
    inline void makeroot(int x){
        access(x);splay(x);pushr(x);
    }
    inline int findroot(int x){
        access(x);splay(x);
        while(c[x][0])pushdown(x),x=c[x][0];
        splay(x);return x;
    }
    inline void link(int x,int y){
        makeroot(x);
        if(findroot(y)!=x)f[x]=y;
    }
    inline void cut(int x,int y){
        makeroot(x);
        if(findroot(y)==x&&f[y]==x&&!c[y][0]){
            f[y]=c[x][1]=0;
            pushup(x);
        }
    }
    inline void split(int x,int y){
        makeroot(x);access(y);splay(y);
    }
}k[15];
inline int read(){
    int x=0,f=1;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
    return x*f;
}
map<int,int>vis;
int main(){
    n=read(),m=read(),col=read(),q=read();
    for(int i=1;i<=n;i++)val[i]=read();
    int opt,x,y,z;
    for(int i=1;i<=m;i++){
        x=read(),y=read(),z=read()+1;
        k[z].link(x,y);
        vis[x*10000+y]=vis[y*10000+x]=z;
        k[z].p[x]++;k[z].p[y]++;
    }
    for(int i=1;i<=q;i++){
        opt=read();
        if(opt==0){
            x=read(),y=read();
            for(int j=1;j<=col;j++)
                k[j].splay(x);
            val[x]=y;
        }else if(opt==1){
            x=read(),y=read(),z=read()+1;
            if(!vis[x*10000+y])puts("No such edge.");
            else if(z==vis[x*10000+y])puts("Success.");
            else if(k[z].p[x]==2||k[z].p[y]==2)puts("Error 1.");
            else if(k[z].findroot(x)==k[z].findroot(y))puts("Error 2.");
            else{
                k[vis[x*10000+y]].cut(x,y);
                k[z].link(x,y);
                k[vis[x*10000+y]].p[x]--;
                k[vis[x*10000+y]].p[y]--;
                k[z].p[x]++;
                k[z].p[y]++;
                vis[x*10000+y]=vis[y*10000+x]=z;
                puts("Success.");
            }
        }else{
            z=read()+1,x=read(),y=read();
            if(k[z].findroot(x)!=k[z].findroot(y))puts("-1");
            else{
                k[z].split(x,y);
                printf("%d\n",k[z].mx[y]);
            }
        }
    }
    return 0;
} 

深深地感到自己的弱小。

posted @ 2020-03-19 13:43  syzf2222  阅读(113)  评论(0编辑  收藏  举报