您的位置:首页 > 理论基础 > 计算机网络

bzoj千题计划223:bzoj2816: [ZJOI2012]网络

2018-02-02 08:41 281 查看
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
[2],fa
;
int key
,mx
;
int d
;

bool rev
;

int st
,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';
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: