BZOJ2816:[ZJOI2012]网络——题解

https://www.lydsy.com/JudgeOnline/problem.php?id=2816

https://www.luogu.org/problemnew/show/P2173

有一个无向图G,每个点有个权值,每条边有一个颜色。这个无向图满足以下两个条件:

  1. 对于任意节点连出去的边中,相同颜色的边不超过两条。

  2. 图中不存在同色的环,同色的环指相同颜色的边构成的环。

在这个图上,你要支持以下三种操作:

  1. 修改一个节点的权值。

  2. 修改一条边的颜色。

  3. 查询由颜色c的边构成的图中,所有可能在节点u到节点v之间的简单路径上的节点的权值的最大值。

这题只要知道什么数据结构,就暴力大模拟即可。

那显然给你的每种颜色组成的图形是一条链,所以使用LCT。

然后对每种颜色建LCT即可。

(纯码农题没有板子情况下1.5h写完1A,这速度怕不是药丸?)

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cctype>
#include<cstdio>
#include<vector>
#include<queue>
#include<cmath>
using namespace std;
const int N=1e5+5;
const int C=11;
int n,m,c,k,r,fa[C][N],tr[C][N][2],d[C][N];
int rev[C][N],q[N],key[N],val[C][N],head[N],cnt=-1;
inline int read(){
    int X=0,w=0;char ch=0;
    while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
    while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
    return w?-X:X;
}
inline bool get(int x,int w){
    return tr[w][fa[w][x]][1]==x;
}
inline bool isroot(int x,int w){
    if(!fa[w][x])return 1;
    return tr[w][fa[w][x]][0]!=x&&tr[w][fa[w][x]][1]!=x;
}
inline void pushrev(int x,int w){
    if(!rev[w][x])return;
    swap(tr[w][x][0],tr[w][x][1]);
    if(tr[w][x][0])rev[w][tr[w][x][0]]^=1;
    if(tr[w][x][1])rev[w][tr[w][x][1]]^=1;
    rev[w][x]=0;
}
inline void upt(int x,int w){
    val[w][x]=key[x];
    if(tr[w][x][0])val[w][x]=max(val[w][x],val[w][tr[w][x][0]]);
    if(tr[w][x][1])val[w][x]=max(val[w][x],val[w][tr[w][x][1]]);
}
inline void rotate(int x,int w){
    int y=fa[w][x],z=fa[w][y],which=get(x,w);
    if(z&&!isroot(y,w))tr[w][z][tr[w][z][1]==y]=x;
    tr[w][y][which]=tr[w][x][which^1];fa[w][tr[w][y][which]]=y;
    fa[w][y]=x;tr[w][x][which^1]=y;fa[w][x]=z;
    upt(y,w);upt(x,w);
}
inline void splay(int x,int w){
    q[r=0]=x;
    for(int y=x;!isroot(y,w);y=fa[w][y])q[++r]=fa[w][y];
    for(int i=r;i>=0;i--)pushrev(q[i],w);
    while(!isroot(x,w)){
    if(!isroot(fa[w][x],w))
        rotate(get(x,w)==get(fa[w][x],w)?fa[w][x]:x,w);
    rotate(x,w);
    }
    upt(x,w);
}
inline void access(int x,int w){
    for(int y=0;x;y=x,x=fa[w][x]){
    splay(x,w);tr[w][x][1]=y;
    if(y)fa[w][y]=x;
    }
}
inline int findroot(int x,int w){
    access(x,w);splay(x,w);
    while(pushrev(x,w),tr[w][x][0])x=tr[w][x][0];
    splay(x,w);
    return x;
}
inline void makeroot(int x,int w){
    access(x,w);splay(x,w);
    rev[w][x]^=1;
}
inline void split(int x,int y,int w){
    makeroot(x,w);
    access(y,w);splay(y,w);
}
inline void link(int x,int y,int w){
    d[w][x]++;d[w][y]++;
    makeroot(x,w);
    fa[w][x]=y;
}
inline bool cut(int x,int y,int w){
    split(x,y,w);
    if(tr[w][x][0]||tr[w][x][1]||fa[w][x]!=y||tr[w][y][get(x,w)^1])return 0;
    d[w][x]--;d[w][y]--;
    tr[w][y][0]=0;fa[w][x]=0;
    return 1;
}
int main(){
    memset(head,-1,sizeof(head));
    n=read(),m=read(),c=read(),k=read();
    for(int i=1;i<=n;i++)key[i]=read();
    for(int i=1;i<=m;i++){
    int u=read(),v=read(),w=read();
    link(u,v,w);
    }
    for(int i=1;i<=k;i++){
    int op=read();
    if(op==0){
        int x=read(),y=read();
        key[x]=y;
        for(int j=0;j<=c;j++){
        access(x,j);splay(x,j);
        upt(x,j);
        }
    }
    if(op==1){
        int u=read(),v=read(),w=read();
        int ok=-1;
        for(int j=0;j<=c&&ok==-1;j++){
        if(cut(u,v,j))ok=j;
        }
        if(ok==-1){
        puts("No such edge.");
        continue;
        }
        if(d[w][u]>1||d[w][v]>1){
        puts("Error 1.");
        link(u,v,ok);
        continue;
        }
        if(findroot(u,w)==findroot(v,w)){
        puts("Error 2.");
        link(u,v,ok);
        continue;
        }
        puts("Success.");
        link(u,v,w);
    }
    if(op==2){
        int w=read(),u=read(),v=read();
        split(u,v,w);
        if(findroot(u,w)!=findroot(v,w)){
        puts("-1");
        continue;
        }
        split(u,v,w);
        printf("%d\n",val[w][v]);
    }
    }
    return 0;
}

+++++++++++++++++++++++++++++++++++++++++++

+本文作者:luyouqi233。               +

+欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+

+++++++++++++++++++++++++++++++++++++++++++

posted @ 2018-04-02 15:55  luyouqi233  阅读(138)  评论(0编辑  收藏  举报