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


    传送门

    题解

    话说以前还真没见过用LCT只维护一条链的……好像除了树点涂色那题……

    先看一下题目规定的两个性质

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

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

    很明显了,同一种颜色肯定是由几条链组成的(虽然我根本没有发现)

    然后又要查询边权和维护路径……直接上LCT吧

    然后颜色数很少啊……每一个颜色开一个LCT好了

    更改权值的话在每一个LCT上splay一下

    修改颜色的话在原来的LCT中cut,新的LCT中link

    查询路径直接split出来

    然后差不多就这样了

      1 //minamoto
      2 #include<cstdio>
      3 #include<map>
      4 #include<iostream>
      5 using std::swap;
      6 using std::map;
      7 template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
      8 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
      9 char buf[1<<21],*p1=buf,*p2=buf;
     10 inline int read(){
     11     #define num ch-'0'
     12     char ch;bool flag=0;int res;
     13     while(!isdigit(ch=getc()))
     14     (ch=='-')&&(flag=true);
     15     for(res=num;isdigit(ch=getc());res=res*10+num);
     16     (flag)&&(res=-res);
     17     #undef num
     18     return res;
     19 }
     20 const int N=10005;
     21 int n,m,val[N],c,k;
     22 struct link_cut_tree{
     23     int fa[N],ch[N][2],rev[N],mx[N],cnt[N],s[N],top;
     24     inline bool isroot(int x){return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;}
     25     inline void pushup(int x){
     26         mx[x]=val[x];int l=ch[x][0],r=ch[x][1];
     27         if(l) cmax(mx[x],mx[l]);
     28         if(r) cmax(mx[x],mx[r]);
     29     }
     30     inline void pushdown(int x){
     31         if(x&&rev[x]){
     32             swap(ch[x][0],ch[x][1]);
     33             rev[ch[x][0]]^=1,rev[ch[x][1]]^=1;
     34             rev[x]=0;
     35         }
     36     }
     37     void rotate(int x){
     38         int y=fa[x],z=fa[y],d=ch[y][1]==x;
     39         if(!isroot(y)) ch[z][ch[z][1]==y]=x;
     40         fa[x]=z,fa[y]=x,fa[ch[x][d^1]]=y,ch[y][d]=ch[x][d^1],ch[x][d^1]=y,pushup(y);
     41     }
     42     void splay(int x){
     43         s[top=1]=x;for(int i=x;!isroot(i);i=fa[i]) s[++top]=fa[i];
     44         while(top) pushdown(s[top--]);
     45         for(int y=fa[x],z=fa[y];!isroot(x);y=fa[x],z=fa[y]){
     46             if(!isroot(y))
     47             ((ch[y][1]==x)^(ch[z][1]==y))?rotate(x):rotate(y);
     48             rotate(x);
     49         }
     50         pushup(x);
     51     }
     52     void access(int x){
     53         for(int y=0;x;x=fa[y=x])
     54         splay(x),ch[x][1]=y,pushup(x);
     55     }
     56     void makeroot(int x){
     57         access(x),splay(x),rev[x]^=1;
     58     }
     59     void split(int x,int y){
     60         makeroot(x),access(y),splay(y);
     61     }
     62     inline void link(int x,int y){
     63         ++cnt[x],++cnt[y],makeroot(x),fa[x]=y,splay(x);
     64     }
     65     inline void cut(int x,int y){
     66         --cnt[x],--cnt[y],split(x,y),fa[x]=ch[y][0]=0,pushup(y);
     67     }
     68     int findroot(int x){
     69         access(x),splay(x),pushdown(x);
     70         while(ch[x][0]) pushdown(x=ch[x][0]);
     71         return x;
     72     }
     73     inline int query(int x,int y){
     74         split(x,y);return mx[y];
     75     }
     76 }lct[15];
     77 struct edge{
     78     int u,v;
     79     inline bool operator <(const edge &b)const
     80     {return u<b.u||(u==b.u&&v<b.v);}
     81 };
     82 map<edge,int> mp;
     83 int main(){
     84     //freopen("testdata.in","r",stdin);
     85     n=read(),m=read(),c=read(),k=read();
     86     for(int i=1;i<=n;++i) val[i]=read();
     87     for(int i=1;i<=m;++i){
     88         int u=read(),v=read(),w=read();
     89         edge e1=(edge){u,v},e2=(edge){v,u};
     90         mp[e1]=mp[e2]=w;
     91         lct[w].link(u,v);
     92     }
     93     while(k--){
     94         int opt=read();
     95         switch(opt){
     96             case 0:{
     97                 int x=read(),w=read();
     98                 val[x]=w;
     99                 for(int i=0;i<c;++i) lct[i].splay(x);
    100                 break;
    101             }
    102             case 1:{
    103                 int u=read(),v=read(),w=read();
    104                 edge a=(edge){u,v},b=(edge){v,u};
    105                 if(!mp.count(a)){puts("No such edge.");continue;}
    106                 int x=mp[a];
    107                 if(x==w){puts("Success.");continue;}
    108                 if(lct[w].cnt[u]>=2||lct[w].cnt[v]>=2){puts("Error 1.");continue;}
    109                 if(lct[w].findroot(u)==lct[w].findroot(v)){puts("Error 2.");continue;}
    110                 puts("Success.");
    111                 lct[x].cut(u,v),lct[w].link(u,v);
    112                 mp[a]=mp[b]=w;
    113                 break;
    114             }
    115             case 2:{
    116                 int w=read(),u=read(),v=read();
    117                 if(lct[w].findroot(u)!=lct[w].findroot(v)){puts("-1");continue;}
    118                 printf("%d
    ",lct[w].query(u,v));
    119                 break;
    120             }
    121         }
    122     }
    123     return 0;
    124 }
  • 相关阅读:
    那些创业的艰辛整理
    一个成功的研发团队应具备的9大属性
    如何将 Linux 系统转移至 LVM 卷
    如何在 Linux 上永久挂载一个 Windows 共享
    怎样在 Chromebook 上安装 Linux 系统?
    1087 有多少不同的值 (20 分)C语言
    1052 卖个萌 (20 分)C语言
    1064 朋友数 (20 分)C语言
    1045 快速排序 (25 分)C语言
    1048 数字加密 (20 分)C语言
  • 原文地址:https://www.cnblogs.com/bztMinamoto/p/9425443.html
Copyright © 2020-2023  润新知