• Luogu P2173 [ZJOI2012]网络


    题意

    写的比较清楚,我就不解释了。

    ( exttt{Data Range:}nleq 10^4,mleq 10^5,cleq 10,kleq 10^5)

    题解

    注意到 (c) 的范围很小,而且把每种颜色的边抠出来发现是一个森林(准确的来说是每个连通块都是链),于是我们可以对每种颜色都开个 ( exttt{LCT})

    然后这题就基本上是板子题了,但是这题细节很多,可能会花费你很多的调试时间。

    有一个坑点就是当修改 ((u,v)) 这条边的颜色的时候如果新的颜色等于原来的颜色无论怎样都是成功的,因为保证每一次操作后的图是满足性质的。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    typedef int ll;
    typedef long long int li;
    const ll MAXN=2e5+51;
    struct Edge{
        ll to,prev,col;
    };
    Edge ed[MAXN<<1];
    ll n,m,c,qcnt,tot,u,v,w,op,col;
    ll deg[MAXN][10],last[MAXN];
    inline ll read()
    {
        register ll num=0,neg=1;
        register char ch=getchar();
        while(!isdigit(ch)&&ch!='-')
        {
            ch=getchar();
        }
        if(ch=='-')
        {
            neg=-1;
            ch=getchar();
        }
        while(isdigit(ch))
        {
            num=(num<<3)+(num<<1)+(ch-'0');
            ch=getchar();
        }
        return num*neg;
    }
    namespace LCT{
        struct Node{
            ll fa,mx,val,rv,sz;
            ll ch[2];
        };
        struct LinkCutTree{
            Node nd[MAXN];
            ll st[MAXN];
            #define ls nd[x].ch[0]
            #define rs nd[x].ch[1]
            inline bool nroot(ll x)
            {
                return nd[nd[x].fa].ch[0]==x||nd[nd[x].fa].ch[1]==x;
            }
            inline void update(ll x)
            {
                nd[x].mx=max(max(nd[x].val,nd[ls].mx),nd[rs].mx);
            }
            inline void reverse(ll x)
            {
                swap(ls,rs),nd[x].rv^=1;
            }
            inline void spread(ll x)
            {
                if(nd[x].rv)
                {
                    ls?reverse(ls):(void)(1),rs?reverse(rs):(void)(1);
                    nd[x].rv=0;
                }
            }
            inline void rotate(ll x)
            {
                ll fa=nd[x].fa,gfa=nd[fa].fa;
                ll dir=nd[fa].ch[1]==x,son=nd[x].ch[!dir];
                if(nroot(fa))
                {
                    nd[gfa].ch[nd[gfa].ch[1]==fa]=x;
                }
                nd[x].ch[!dir]=fa,nd[fa].ch[dir]=son;
                if(son)
                {
                    nd[son].fa=fa;
                }
                nd[fa].fa=x,nd[x].fa=gfa,update(fa);
            }
            inline void splay(ll x)
            {
                ll fa=x,gfa,cur=0;
                st[++cur]=fa;
                while(nroot(fa))
                {
                    st[++cur]=fa=nd[fa].fa;
                }
                while(cur)
                {
                    spread(st[cur--]);
                }
                while(nroot(x))
                {
                    fa=nd[x].fa,gfa=nd[fa].fa;
                    if(nroot(fa))
                    {
                        rotate((nd[fa].ch[0]==x)^(nd[gfa].ch[0]==fa)?x:fa);
                    }
                    rotate(x);
                }
                update(x);
            }
            inline void access(ll x)
            {
                for(register int i=0;x;x=nd[i=x].fa)
                {
                    splay(x),rs=i,update(x);
                }
            }
            inline void makeRoot(ll x)
            {
                access(x),splay(x),reverse(x);
            }
            inline ll findRoot(ll x)
            {
                access(x),splay(x);
                while(ls)
                {
                    spread(x),x=ls;
                }
                return x;
            }
            inline void split(ll x,ll y)
            {
                makeRoot(x),access(y),splay(y);
            }
            inline void link(ll x,ll y)
            {
                makeRoot(x);
                if(findRoot(y)!=x)
                {
                    nd[x].fa=y;
                }
            }
            inline void cut(ll x,ll y)
            {
                makeRoot(x);
                if(findRoot(y)==x&&nd[x].fa==y&&!rs)
                {
                    nd[x].fa=nd[y].ch[0]=0,update(y);
                }
            }
            #undef ls
            #undef rs
        };
    }
    LCT::LinkCutTree lct[10];
    inline void addEdge(ll from,ll to,ll col)
    {
        ed[++tot].prev=last[from];
        ed[tot].to=to;
        ed[tot].col=col;
        last[from]=tot;
    }
    inline bool check(ll u,ll v,ll w)
    {
        ll col=-1;
        for(register int i=last[u];i;i=ed[i].prev)
        {
            if(ed[i].to==v)
            {
                col=ed[i].col;
                break;
            }
        }
        if(col==-1)
        {
            return puts("No such edge."),0;
        }
        if(w==col)
        {
            return puts("Success."),1;
        }
        if(deg[u][w]==2||deg[v][w]==2)
        {
            return puts("Error 1."),0;
        }
        if(lct[w].findRoot(u)==lct[w].findRoot(v))
        {
            return puts("Error 2."),0;
        }
        return puts("Success."),1;
    }
    int main()
    {
        n=read(),m=read(),c=read(),qcnt=read();
        for(register int i=1;i<=n;i++)
        {
            v=read();
            for(register int j=0;j<c;j++)
            {
                lct[j].nd[i].val=v;
            }
        }
        for(register int i=0;i<m;i++)
        {
            u=read(),v=read(),w=read(),lct[w].link(u,v);
            deg[u][w]++,deg[v][w]++,addEdge(u,v,w),addEdge(v,u,w);
        }
        for(register int i=0;i<qcnt;i++)
        {
            op=read(),u=read(),v=read();
            if(op==0)
            {
                for(register int j=0;j<c;j++)
                {
                    lct[j].splay(u),lct[j].nd[u].val=v;
                }
            }
            if(op==1)
            {
                if(check(u,v,w=read()))
                {
                    for(register int j=last[u];j;j=ed[j].prev)
                    {
                        if(ed[j].to==v)
                        {
                            col=ed[j].col,ed[j].col=w;
                            break;
                        }
                    }
                    for(register int j=last[v];j;j=ed[j].prev)
                    {
                        if(ed[j].to==u)
                        {
                            ed[j].col=w;
                            break;
                        }
                    }
                    lct[col].cut(u,v),lct[w].link(u,v);
                    deg[u][col]--,deg[v][col]--,deg[u][w]++,deg[v][w]++;
                }
            }
            if(op==2)
            {
                w=read(),swap(u,w);
                if(lct[w].findRoot(u)!=lct[w].findRoot(v))
                {
                    puts("-1");
                    continue;
                }
                lct[w].split(u,v),printf("%d
    ",lct[w].nd[v].mx);
            }
        }
    }
    
  • 相关阅读:
    UML模型的基本概念
    Asp.net 2.0 发送电子邮件
    生活多了些颜色
    FLASH调用网页上的JS方法,以及FLASH全屏播放的方法
    HTC编程思想
    实用的SQL精妙语句
    自己写的封装好的简单的AJAXjavascript
    SQL Server对象名
    windows开关机日志
    RegisterWindowMessage
  • 原文地址:https://www.cnblogs.com/Karry5307/p/13044884.html
Copyright © 2020-2023  润新知