码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2018-03-23 14:13:11      阅读:205      评论:0      收藏:0      [点我收藏+]

标签:dig   lct   put   strong   ret   code   make   type   problem   

题目链接 BZOJ
洛谷

对每种颜色维护一个LCT,保存点之间的连接关系。
修改权值A[x]和所有Max[x]都要改;
修改边的颜色先枚举所有颜色,看是否在某种颜色中有边,然后断开。(枚举一遍就行啊 还以为要set什么的存边的颜色)
(条件1直接用数组存233)
修改x的颜色必须先把x旋到根再改!

(好像只能是条链啊)

//3364kb    5952ms
#include <cstdio>
#include <cctype>
#include <algorithm>
#define gc() getchar()
const int N=1e4+5;

int n,m,C,q,A[N],num[N][11];
struct LCT
{
    #define lson son[x][0]
    #define rson son[x][1]

    int fa[N],son[N][2],Max[N],sk[N];
    bool tag[N];
    inline void Update(int x){
        Max[x]=std::max(A[x],std::max(Max[lson],Max[rson]));
    }
    inline bool n_root(int x){
        return son[fa[x]][0]==x||son[fa[x]][1]==x;
    }
    inline void Rev(int x){
        std::swap(lson,rson), tag[x]^=1;
    }
    inline void PushDown(int x){
        if(tag[x]) Rev(lson),Rev(rson),tag[x]=0;
    }
    void Rotate(int x)
    {
        int a=fa[x],b=fa[a],l=son[a][1]==x,r=l^1;
        if(n_root(a)) son[b][son[b][1]==a]=x;
        if(son[x][r]) fa[son[x][r]]=a;
        fa[a]=x, fa[x]=b, son[a][l]=son[x][r], son[x][r]=a;
        Update(a);
    }
    void Splay(int x)
    {
        int t=1,a=x; sk[1]=x;
        while(n_root(a)) sk[++t]=a=fa[a];
        while(t) PushDown(sk[t--]);
        while(n_root(x))
        {
            a=fa[x];
            if(n_root(a)) Rotate(son[a][1]==x^son[fa[a]][1]==a?x:a);
            Rotate(x);
        }
        Update(x);
    }
    void Access(int x){
        for(int pre=0; x; x=fa[pre=x])
            Splay(x), rson=pre, Update(x);
    }
    void Make_root(int x){
        Access(x), Splay(x), Rev(x);
    }
    void Split(int x,int y){
        Make_root(x), Access(y), Splay(y);
    }
    int Find_root(int x)
    {
        Access(x), Splay(x);
        while(lson) x=lson;
        return x;
    }
    bool pre_Link(int x,int y){
        Make_root(x);
        return Find_root(y)!=x;
    }
    void Link(int x,int y){
        fa[x]=y;
    }
    bool pre_Cut(int x,int y){
        Make_root(x);
        return Find_root(y)==x&&fa[x]==y&&!rson;
    }
    void Cut(int x,int y){
        fa[x]=son[y][0]=0, Update(y);
    }
    void Modify(int x,int col){//修改颜色 
        Access(x), Splay(x), Update(x);
    }
}t[10];
inline int read()
{
    int now=0,f=1;register char c=gc();
    for(;!isdigit(c);c=gc()) if(c=='-') f=-1;
    for(;isdigit(c);now=now*10+c-'0',c=gc());
    return now*f;
}

int main()
{
    n=read(),m=read(),C=read(),q=read();
    for(int i=1; i<=n; ++i) A[i]=read();
    for(int u,v,w,i=1; i<=m; ++i)
        u=read(),v=read(),w=read(),++num[u][w],++num[v][w],t[w].pre_Link(u,v),t[w].Link(u,v);
    int opt,c,x,y,pos;
    while(q--)
    {
        opt=read();
        if(!opt){
            x=read(),A[x]=y=read();
            for(int i=0; i<C; ++i) t[i].Modify(x,y);
        }
        else if(opt==1){
            x=read(),y=read(),c=read(),pos=-1;
            for(int i=0; i<C; ++i)
                if(t[i].pre_Cut(x,y)) {pos=i; break;}
            if(~pos){
                if(pos==c) puts("Success.");//这个要判!
                else if(num[x][c]>=2||num[y][c]>=2) puts("Error 1.");
                else if(!t[c].pre_Link(x,y)) puts("Error 2.");
                else t[c].Link(x,y),t[pos].Cut(x,y),--num[x][pos],--num[y][pos],++num[x][c],++num[y][c],puts("Success.");
            }
            else puts("No such edge.");
        }
        else{
            c=read(),x=read(),y=read();
            if(!t[c].pre_Link(x,y)) t[c].Split(x,y), printf("%d\n",t[c].Max[y]);
            else puts("-1");
        }
    }
    return 0;
}

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

标签:dig   lct   put   strong   ret   code   make   type   problem   

原文地址:https://www.cnblogs.com/SovietPower/p/8629672.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!