BZOJ2816ZJOI2012网络(Link-Cut Tree)

Posted 小蒟蒻yyb的博客

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ2816ZJOI2012网络(Link-Cut Tree)相关的知识,希望对你有一定的参考价值。

【BZOJ2816】【ZJOI2012】网络(Link-Cut Tree)

题面

题目描述

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

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

图中不存在同色的环,同色的环指相同颜色的边构成的环。
在这个图上,你要支持以下三种操作:

修改一个节点的权值。

修改一条边的颜色。

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

输入输出格式

输入格式:
输入文件network.in的第一行包含四个正整数N, M, C, K,其中N为节点个数,M为边数,C为边的颜色数,K为操作数。

接下来N行,每行一个正整数vi,为节点i的权值。

之后M行,每行三个正整数u, v, w,为一条连接节点u和节点v的边,颜色为w。满足1 ≤ u, v ≤ N,0 ≤ w < C,保证u ≠ v,且任意两个节点之间最多存在一条边(无论颜色)。

最后K行,每行表示一个操作。每行的第一个整数k表示操作类型。

k = 0为修改节点权值操作,之后两个正整数x和y,表示将节点x的权值vx修改为y。

k = 1为修改边的颜色操作,之后三个正整数u, v和w,表示将连接节点u和节点v的边的颜色修改为颜色w。满足0 ≤ w < C。

k = 2为查询操作,之后三个正整数c, u和v,表示查询所有可能在节点u到节点v之间的由颜色c构成的简单路径上的节点的权值的最大值。如果不存在u和v之间不存在由颜色c构成的路径,那么输出“-1”。
输出格式:
输出文件network.out包含若干行,每行输出一个对应的信息。

对于修改节点权值操作,不需要输出信息。

对于修改边的颜色操作,按以下几类输出:

a) 若不存在连接节点u和节点v的边,输出“No such edge.”。

b) 若修改后不满足条件1,不修改边的颜色,并输出“Error 1.”。

c) 若修改后不满足条件2,不修改边的颜色,并输出“Error 2.”。

d) 其他情况,成功修改边的颜色,并输出“Success.”。

输出满足条件的第一条信息即可,即若同时满足b和c,则只需要输出“Error 1.”。

对于查询操作,直接输出一个整数。

输入输出样例

输入样例#1:
4 5 2 7
1
2
3
4
1 2 0
1 3 1
2 3 0
2 4 1
3 4 0
2 0 1 4
1 1 2 1
1 4 3 1
2 0 1 4
1 2 3 1
0 2 5
2 1 1 4
输出样例#1:
4
Success.
Error 2.
-1
Error 1.
5

题解

考虑\(C<=10\)
那么, 暴力维护\(C\)棵树即可
直接\(LCT\)维护即可
细节真的是有点多。。。
这道题目慢慢做。。。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define MAX 11000
#define fat t[x].ff
#define lson t[x].ch[0]
#define rson t[x].ch[1]
inline int read()
{
    int x=0,t=1;char ch=getchar();
    while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
    if(ch=='-')t=-1,ch=getchar();
    while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
    return x*t;
}
int S[MAX],top;
struct N{int u,v;};
int n,m,C,K,val[MAX];
int color[MAX][11];
bool operator<(N a,N b)
{
    if(a.u!=b.u)return a.u<b.u;
    return a.v<b.v;
}
map<N,int> MM;
struct Node
{
    int ch[2],ff;
    int mm,val,rev; 
};
struct LCT
{
    struct Node t[MAX];
    void pushup(int x){t[x].mm=max(t[lson].mm,t[rson].mm);t[x].mm=max(t[x].mm,t[x].val);}
    bool isroot(int x){return t[fat].ch[0]!=x&&t[fat].ch[1]!=x;}
    void pushdown(int x)
    {
        if(!t[x].rev)return;
        swap(lson,rson);
        t[lson].rev^=1;t[rson].rev^=1;
        t[x].rev^=1;
    }
    void rotate(int x)
    {
        int y=t[x].ff,z=t[y].ff;
        int k=t[y].ch[1]==x;
        if(!isroot(y))t[z].ch[t[z].ch[1]==y]=x;t[x].ff=z;
        t[y].ch[k]=t[x].ch[k^1];t[t[x].ch[k^1]].ff=y;
        t[x].ch[k^1]=y;t[y].ff=x;   
        pushup(y);pushup(x);    
    }
    void Splay(int x)
    {
        S[top=1]=x;
        for(int i=x;!isroot(i);i=t[i].ff)S[++top]=t[i].ff;
        while(top)pushdown(S[top--]);
        while(!isroot(x))
        {
            int y=t[x].ff,z=t[y].ff;
            if(!isroot(y))
                (t[y].ch[0]==x)^(t[z].ch[0]==y)?rotate(x):rotate(y);
            rotate(x);
        }
    }
    void access(int x){for(int y=0;x;y=x,x=t[x].ff)Splay(x),t[x].ch[1]=y,pushup(x);}
    void makeroot(int x){access(x);Splay(x);t[x].rev^=1;}
    void split(int x,int y){makeroot(x);access(y);Splay(y);}
    void cut(int x,int y){split(x,y);t[y].ch[0]=t[x].ff=0;}
    void link(int x,int y){makeroot(x);t[x].ff=y;}
    int findroot(int x){access(x);Splay(x);while(lson)x=lson;return x;}
}LCT[11];
int main()
{
    n=read();m=read();C=read();K=read();
    for(int i=1;i<=n;++i)val[i]=read();
    for(int i=1;i<=n;++i)
        for(int j=1;j<=C;++j)
            LCT[j].t[i].val=val[i];
    for(int i=1,u,v,w;i<=m;++i)
    {
        u=read(),v=read(),w=read()+1;
        MM[(N){u,v}]=w;
        MM[(N){v,u}]=w;
        color[u][w]++;color[v][w]++;
        LCT[w].link(u,v);
    }
    while(K--)
    {
        int opt=read();
        if(opt==0)
        {
            int x=read();val[x]=read();
            for(int i=1;i<=C;++i)
            {
                LCT[i].access(x);
                LCT[i].Splay(x);
                LCT[i].t[x].val=val[x];
            }
        }
        else if(opt==1)
        {
            int u=read(),v=read(),w=read()+1;
            int G=MM[(N){u,v}];
            if(!G){puts("No such edge.");continue;}
            if(G==w){puts("Success.");continue;}
            if(color[u][w]>1||color[v][w]>1){puts("Error 1.");continue;}
            if(LCT[w].findroot(u)==LCT[w].findroot(v)){puts("Error 2.");continue;}
            color[u][w]++;color[v][w]++;
            color[u][G]--;color[v][G]--;
            MM[(N){u,v}]=w;MM[(N){v,u}]=w;
            LCT[G].cut(u,v);
            LCT[w].link(u,v);
            puts("Success.");
        }
        else
        {
            int w=read()+1,u=read(),v=read();
            if(LCT[w].findroot(u)!=LCT[w].findroot(v)){puts("-1");continue;}
            LCT[w].split(u,v);
            printf("%d\n",LCT[w].t[v].mm);
        }
    }
    return 0;
}

以上是关于BZOJ2816ZJOI2012网络(Link-Cut Tree)的主要内容,如果未能解决你的问题,请参考以下文章

bzoj 2816: [ZJOI2012]网络(splay)

刷题BZOJ 2816 [ZJOI2012]网络

BZOJ.2816.[ZJOI2012]网络(LCT)

BZOJ2816ZJOI2012网络(Link-Cut Tree)

[bzoj2816][ZJOI2012]网络(LCT,splay)

2816. [ZJOI2012]网络LCT