[ZJOI2012]网络 LCT
作者:互联网
lct忘了。。重新学习。
链接:https://www.luogu.org/problemnew/show/P2173
每个颜色开个lct即可。
代码:
#include<bits/stdc++.h>
using namespace std;
const int N=1e4+100;
const int C=12;
int a[N];
map<int,int>hav[N];
int n,m,c,k;
struct LCT{
int ch[N][2],fa[N],mx[N],w[N],du[N];bool rev[N];
void in()
{
memset(ch,0,sizeof ch),memset(fa,0,sizeof fa);
memset(du,0,sizeof du),memset(rev,0,sizeof rev);
for(int i=1;i<=n;i++)mx[i]=w[i]=a[i];
}
int get(int x)
{
if(!fa[x])return -1;
if(ch[fa[x]][0]==x)return 0;
if(ch[fa[x]][1]==x)return 1;
return -1;
}
void push_up(int x)
{
mx[x]=w[x];
if(ch[x][0])mx[x]=max(mx[x],mx[ch[x][0]]);
if(ch[x][1])mx[x]=max(mx[x],mx[ch[x][1]]);
}
void R(int x)
{
swap(ch[x][0],ch[x][1]);
rev[x]^=1;
}
void push_down(int x)
{
if(x&&rev[x])
{
if(ch[x][0])R(ch[x][0]);
if(ch[x][1])R(ch[x][1]);
rev[x]=0;
}
}
void push_all(int x)
{
if(get(x)!=-1)push_all(fa[x]);
push_down(x);
}
void rot(int x)
{
int fx=fa[x],gx=fa[fx],op=get(x),fop=get(fx);
ch[fx][op]=ch[x][op^1],fa[ch[x][op^1]]=fx;
ch[x][op^1]=fx,fa[fx]=x;if(fop!=-1)ch[gx][fop]=x;fa[x]=gx;
push_up(fx),push_up(x);
}
void splay(int x)
{
push_all(x);
for(int fx=fa[x];get(x)!=-1;rot(x),fx=fa[x])
if(get(fx)!=-1)get(x)==get(fx)?rot(fx):rot(x);
}
void access(int x)
{
for(int y=0;x;y=x,x=fa[x])
splay(x),ch[x][1]=y,push_up(x);
//cerr<<'?'<<'\n';
}
void make_rt(int x)
{access(x),splay(x),R(x);}
int find_rt(int x)
{
access(x),splay(x);
for(;ch[x][0];)push_down(x),x=ch[x][0];
splay(x);
return x;
}
int line(int x,int y,int op)
{
if(du[x]==2||du[y]==2){if(op)puts("Error 1.");return 0;}
make_rt(x);
if(find_rt(y)==x){if(op)puts("Error 2.");return 0;}
fa[x]=y,du[x]++,du[y]++;
if(op)puts("Success.");
return 1;
}
void cut(int x,int y)
{
make_rt(x),access(y),splay(y);
ch[y][0]=0,fa[x]=0,du[x]--,du[y]--;
push_up(y);
}
void cg(int x,int y)
{splay(x),w[x]=y,push_up(x);}
void qry(int x,int y)
{
//if(x==9&&y==6)cerr<<"!!"<<'\n';
make_rt(x);
//if(x==9&&y==6)cerr<<"!!"<<'\n';
if(find_rt(y)!=x){puts("-1");return;}
splay(y);
printf("%d\n",mx[y]);
}
}lct[C];
int main()
{
scanf("%d%d%d%d",&n,&m,&c,&k);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
for(int i=1;i<=c;i++)
lct[i].in();
int x,y,w,op;
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&x,&y,&w);
++w;
hav[x][y]=hav[y][x]=w;
lct[w].line(x,y,0);
}
for(int i=1;i<=k;i++)
{
scanf("%d",&op);
if(op==0)
{
scanf("%d%d",&x,&y);
for(int j=1;j<=c;j++)
lct[j].cg(x,y);
}
if(op==1)
{
scanf("%d%d%d",&x,&y,&w),++w;
if(hav[x][y]==w){puts("Success.");continue;}
if(!hav[x][y]){puts("No such edge.");continue;}
if(lct[w].line(x,y,1)==1)
{
lct[hav[x][y]].cut(x,y);
hav[x][y]=hav[y][x]=w;
}
}
if(op==2)
{
scanf("%d%d%d",&w,&x,&y),++w;
lct[w].qry(x,y);
}
}
}
标签:LCT,ch,int,memset,rev,网络,fa,ZJOI2012,sizeof 来源: https://blog.csdn.net/caoyang1123/article/details/88091832