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';
}
}
}
轉載于:https://www.cnblogs.com/TheRoadToTheGold/p/8403383.html