[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\n",lct[w].query(u,v));
119                 break;
120             }
121         }
122     }
123     return 0;
124 }

猜你喜欢

转载自www.cnblogs.com/bztMinamoto/p/9425443.html