建10棵动态树就完事了~

#include <bits/stdc++.h>  
#define N 100004       
#define setIO(s) freopen(s".in","r",stdin)  , freopen(s".out","w",stdout)   
using namespace std;
int A[N];   
map<int,int>pp[N],lk[N];             
struct Link_Cut_Tree 
{  
    #define lson t[x].ch[0] 
    #define rson t[x].ch[1] 
    int sta[N];    
    struct Node 
    { 
        int ch[2],f,max,val,rev,son;             
    }t[N];    
    int isrt(int x) 
    {
        return !(t[t[x].f].ch[0]==x||t[t[x].f].ch[1]==x);   
    } 
    int get(int x) 
    {
        return t[t[x].f].ch[1]==x; 
    } 
    void pushup(int x) 
    {
        if(!x) return;   
        t[x].max=t[x].val;  
        if(lson) t[x].max=max(t[x].max, t[lson].max);  
        if(rson) t[x].max=max(t[x].max, t[rson].max);    
    }  
    void mark(int x) 
    {
        if(x) t[x].rev^=1,swap(lson,rson); 
    }
    void pushdown(int x) 
    {
        if(x&&t[x].rev) 
        {
            t[x].rev=0; 
            if(lson) mark(lson); 
            if(rson) mark(rson);    
        }
    }
    void rotate(int x) 
    {
        int old=t[x].f,fold=t[old].f,which=get(x);
        if(!isrt(old)) t[fold].ch[t[fold].ch[1]==old]=x; 
        t[old].ch[which]=t[x].ch[which^1],t[t[old].ch[which]].f=old; 
        t[x].ch[which^1]=old,t[old].f=x,t[x].f=fold; 
        pushup(old),pushup(x); 
    } 
    void splay(int x) 
    {
        int v=0,u=x,fa;  
        for(sta[++v]=u;!isrt(u);u=t[u].f) sta[++v]=t[u].f;       
        for(;v;--v) pushdown(sta[v]);    
        for(u=t[u].f;(fa=t[x].f)!=u;rotate(x)) 
            if(t[fa].f!=u) 
                rotate(get(fa)==get(x)?fa:x);    
    }
    void Access(int x) 
    {
        for(int y=0;x;y=x,x=t[x].f) 
        {
            splay(x); 
            if(rson) t[x].son++;  
            if(y) t[x].son--;  
            rson=y; 
            pushup(x);   
        }
    }
    void makeroot(int x) 
    {
        Access(x),splay(x),mark(x); 
    }  
    void split(int x,int y) 
    {
        makeroot(x),Access(y),splay(y);   
    }
    void link(int x,int y) 
    {
        makeroot(x),makeroot(y),t[x].f=y,t[y].son++;                
    } 
    void cut(int x,int y) 
    {
        makeroot(x),Access(y),splay(y);   
        t[y].ch[0]=t[x].f=0;              
        pushup(y);     
    }
    int find(int x) 
    {
        Access(x),splay(x);     
        for(pushdown(x);lson;pushdown(x)) x=lson;   
        return x;    
    }
    int check(int x) 
    {
        makeroot(x);          
        if(t[x].son==0) return 1;      
        if(t[x].son==1 && !rson) return 1; 
        return 0;     
    }
    #undef lson 
    #undef rson 
}op[10]; 
int main() 
{
    // setIO("input");        
    int n,m,C,K,i,j;   
    scanf("%d%d%d%d",&n,&m,&C,&K);  
    for(i=1;i<=n;++i) 
    {
        scanf("%d",&A[i]);    
        for(j=0;j<C;++j) op[j].t[i].val=A[i];     
    }
    for(i=1;i<=m;++i) 
    {
        int a,b,c; 
        scanf("%d%d%d",&a,&b,&c);        
        op[c].link(a,b);       
        pp[a][b]=pp[b][a]=c;
        lk[a][b]=lk[b][a]=1;           
    }   
    for(i=1;i<=K;++i) 
    {
        int opt; 
        scanf("%d",&opt); 
        if(opt==0) 
        { 
            int x,y;        
            scanf("%d%d",&x,&y);   
            for(j=0;j<C;++j) op[j].makeroot(x), op[j].t[x].val=y, op[j].pushup(x);   
        }
        if(opt==1) 
        {
            int u,v,w; 
            scanf("%d%d%d",&u,&v,&w);            
            if(!lk[u][v]) 
            {
                printf("No such edge.\n");  
            }
            else
            {
                int flag2=0,flag1=0;      
                if(pp[u][v]==w) 
                {
                    printf("Success.\n");   
                }
                else if(op[w].find(u)==op[w].find(v)) 
                {
                    flag2=1;             
                    if(!op[w].check(u) || !op[w].check(v)) flag1=1;    
                }
                else 
                {     
                    op[w].makeroot(u);  
                    op[w].makeroot(v);     
                    if(op[w].check(u)&&op[w].check(v)) 
                    {   
                        op[w].link(u,v);    
                        op[pp[u][v]].cut(u,v);   
                        pp[u][v]=pp[v][u]=w;             
                        printf("Success.\n");               
                    }
                    else 
                    {
                        flag1=1;   
                    }
                }
                if(flag2||flag1) 
                {
              
                    if(flag1) printf("Error 1.\n"); 
                    else printf("Error 2.\n");  
                } 
            }
        }
        if(opt==2) 
        {
            int c,u,v; 
            scanf("%d%d%d",&c,&u,&v);   
            if(op[c].find(u)!=op[c].find(v)) printf("-1\n"); 
            else
            {
                op[c].split(u,v);   
                printf("%d\n",op[c].t[v].max);    
            }
        }
    }
    return 0; 
}