Description
http://www.lydsy.com/JudgeOnline/upload/zjoi2012.pdf
正解:$link-cut tree$。
$LCT$板子题,直接维护$10$个$LCT$就行了。
注意修改颜色操作,修改后的颜色可能与之前颜色相同。
1 #include <bits/stdc++.h> 2 #define il inline 3 #define RG register 4 #define ll long long 5 #define N (10005) 6 7 using namespace std; 8 9 map<int,int> mp[N]; 10 11 int d[N][10],val[N],n,m,c,Q; 12 13 il int gi(){ 14 RG int x=0,q=1; RG char ch=getchar(); 15 while ((ch<'0' || ch>'9') && ch!='-') ch=getchar(); 16 if (ch=='-') q=-1,ch=getchar(); 17 while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar(); 18 return q*x; 19 } 20 21 struct Link_Cut_Tree{ 22 23 int ch[N][2],fa[N],sum[N],rev[N],st[N]; 24 25 il int isroot(RG int x){ 26 return ch[fa[x]][0]!=x && ch[fa[x]][1]!=x; 27 } 28 29 il void pushup(RG int x){ 30 sum[x]=max(val[x],max(sum[ch[x][0]],sum[ch[x][1]])); return; 31 } 32 33 il void pushdown(RG int x){ 34 rev[ch[x][0]]^=1,rev[ch[x][1]]^=1; 35 swap(ch[x][0],ch[x][1]),rev[x]=0; return; 36 } 37 38 il void rotate(RG int x){ 39 RG int y=fa[x],z=fa[y],k=ch[y][0]==x; 40 if (!isroot(y)) ch[z][ch[z][1]==y]=x; 41 fa[x]=z,ch[y][k^1]=ch[x][k],fa[ch[x][k]]=y; 42 ch[x][k]=y,fa[y]=x,pushup(y),pushup(x); return; 43 } 44 45 il void splay(RG int x){ 46 RG int top=0; st[++top]=x; 47 for (RG int i=x;!isroot(i);i=fa[i]) st[++top]=fa[i]; 48 for (RG int i=top;i;--i) if (rev[st[i]]) pushdown(st[i]); 49 while (!isroot(x)){ 50 RG int y=fa[x],z=fa[y]; 51 if (!isroot(y)) rotate((ch[z][0]==y)^(ch[y][0]==x)?x:y); 52 rotate(x); 53 } 54 return; 55 } 56 57 il void access(RG int x){ 58 RG int t=0; 59 while (x){ 60 splay(x),ch[x][1]=t; 61 pushup(x),t=x,x=fa[x]; 62 } 63 return; 64 } 65 66 il void makeroot(RG int x){ 67 access(x),splay(x),rev[x]^=1; return; 68 } 69 70 il void link(RG int x,RG int y){ 71 makeroot(x),fa[x]=y; return; 72 } 73 74 il void cut(RG int x,RG int y){ 75 makeroot(x),access(y),splay(y); 76 ch[y][0]=fa[x]=0,pushup(y); return; 77 } 78 79 il int query(RG int x,RG int y){ 80 makeroot(x),access(y),splay(y); return sum[y]; 81 } 82 83 il int find(RG int x){ 84 access(x),splay(x); 85 while (ch[x][0]) x=ch[x][0]; return x; 86 } 87 88 }G[10]; 89 90 int main(){ 91 #ifndef ONLINE_JUDGE 92 freopen("network.in","r",stdin); 93 freopen("network.out","w",stdout); 94 #endif 95 n=gi(),m=gi(),c=gi(),Q=gi(); 96 for (RG int i=1;i<=n;++i) val[i]=gi(); 97 for (RG int i=1,u,v,w;i<=m;++i){ 98 u=gi(),v=gi(),w=gi(); if (u>v) swap(u,v); 99 G[w].link(u,v),mp[u][v]=w,++d[u][w],++d[v][w]; 100 } 101 while (Q--){ 102 RG int op=gi(); 103 if (!op){ 104 RG int x=gi(),y=gi(); 105 for (RG int i=0;i<c;++i) G[i].splay(x); val[x]=y; 106 for (RG int i=0;i<c;++i) G[i].pushup(x); 107 } else if (op==1){ 108 RG int u=gi(),v=gi(),w=gi(),k; if (u>v) swap(u,v); 109 if (!mp[u].count(v)){ puts("No such edge."); continue; } k=mp[u][v]; 110 if (k!=w && (d[u][w]>=2 || d[v][w]>=2)) puts("Error 1."); 111 else if (k!=w && G[w].find(u)==G[w].find(v)) puts("Error 2."); else{ 112 RG int k=mp[u][v]; --d[u][k],--d[v][k],++d[u][w],++d[v][w]; 113 G[k].cut(u,v),G[w].link(u,v),mp[u][v]=w,puts("Success."); 114 } 115 } else{ 116 RG int w=gi(),u=gi(),v=gi(); 117 if (G[w].find(u)!=G[w].find(v)) puts("-1"); 118 else printf("%d ",G[w].query(u,v)); 119 } 120 } 121 return 0; 122 }