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]<<'\n'; } } }