[bzoj2816][ZJOI2012]网络(LCT,splay)
题解
话说以前还真没见过用LCT只维护一条链的……好像除了树点涂色那题……
先看一下题目规定的两个性质
对于任意节点连出去的边中,相同颜色的边不超过两条。
图中不存在同色的环,同色的环指相同颜色的边构成的环。
很明显了,同一种颜色肯定是由几条链组成的(虽然我根本没有发现)
然后又要查询边权和维护路径……直接上LCT吧
然后颜色数很少啊……每一个颜色开一个LCT好了
更改权值的话在每一个LCT上splay一下
修改颜色的话在原来的LCT中cut,新的LCT中link
查询路径直接split出来
然后差不多就这样了
//minamoto
#include<cstdio>
#include<map>
#include<iostream>
using std::swap;
using std::map;
template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,:;}
#define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[<<],*p1=buf,*p2=buf;
inline int read(){
#define num ch-'0'
char ch;bool flag=;int res;
while(!isdigit(ch=getc()))
(ch=='-')&&(flag=true);
for(res=num;isdigit(ch=getc());res=res*+num);
(flag)&&(res=-res);
#undef num
return res;
}
const int N=;
int n,m,val[N],c,k;
struct link_cut_tree{
int fa[N],ch[N][],rev[N],mx[N],cnt[N],s[N],top;
inline bool isroot(int x){return ch[fa[x]][]!=x&&ch[fa[x]][]!=x;}
inline void pushup(int x){
mx[x]=val[x];int l=ch[x][],r=ch[x][];
if(l) cmax(mx[x],mx[l]);
if(r) cmax(mx[x],mx[r]);
}
inline void pushdown(int x){
if(x&&rev[x]){
swap(ch[x][],ch[x][]);
rev[ch[x][]]^=,rev[ch[x][]]^=;
rev[x]=;
}
}
void rotate(int x){
int y=fa[x],z=fa[y],d=ch[y][]==x;
if(!isroot(y)) ch[z][ch[z][]==y]=x;
fa[x]=z,fa[y]=x,fa[ch[x][d^]]=y,ch[y][d]=ch[x][d^],ch[x][d^]=y,pushup(y);
}
void splay(int x){
s[top=]=x;for(int i=x;!isroot(i);i=fa[i]) s[++top]=fa[i];
while(top) pushdown(s[top--]);
for(int y=fa[x],z=fa[y];!isroot(x);y=fa[x],z=fa[y]){
if(!isroot(y))
((ch[y][]==x)^(ch[z][]==y))?rotate(x):rotate(y);
rotate(x);
}
pushup(x);
}
void access(int x){
for(int y=;x;x=fa[y=x])
splay(x),ch[x][]=y,pushup(x);
}
void makeroot(int x){
access(x),splay(x),rev[x]^=;
}
void split(int x,int y){
makeroot(x),access(y),splay(y);
}
inline void link(int x,int y){
++cnt[x],++cnt[y],makeroot(x),fa[x]=y,splay(x);
}
inline void cut(int x,int y){
--cnt[x],--cnt[y],split(x,y),fa[x]=ch[y][]=,pushup(y);
}
int findroot(int x){
access(x),splay(x),pushdown(x);
while(ch[x][]) pushdown(x=ch[x][]);
return x;
}
inline int query(int x,int y){
split(x,y);return mx[y];
}
}lct[];
struct edge{
int u,v;
inline bool operator <(const edge &b)const
{return u<b.u||(u==b.u&&v<b.v);}
};
map<edge,int> mp;
int main(){
//freopen("testdata.in","r",stdin);
n=read(),m=read(),c=read(),k=read();
for(int i=;i<=n;++i) val[i]=read();
for(int i=;i<=m;++i){
int u=read(),v=read(),w=read();
edge e1=(edge){u,v},e2=(edge){v,u};
mp[e1]=mp[e2]=w;
lct[w].link(u,v);
}
while(k--){
int opt=read();
switch(opt){
case :{
int x=read(),w=read();
val[x]=w;
for(int i=;i<c;++i) lct[i].splay(x);
break;
}
case :{
int u=read(),v=read(),w=read();
edge a=(edge){u,v},b=(edge){v,u};
if(!mp.count(a)){puts("No such edge.");continue;}
int x=mp[a];
if(x==w){puts("Success.");continue;}
if(lct[w].cnt[u]>=||lct[w].cnt[v]>=){puts("Error 1.");continue;}
if(lct[w].findroot(u)==lct[w].findroot(v)){puts("Error 2.");continue;}
puts("Success.");
lct[x].cut(u,v),lct[w].link(u,v);
mp[a]=mp[b]=w;
break;
}
case :{
int w=read(),u=read(),v=read();
if(lct[w].findroot(u)!=lct[w].findroot(v)){puts("-1");continue;}
printf("%d\n",lct[w].query(u,v));
break;
}
}
}
return ;
}
[bzoj2816][ZJOI2012]网络(LCT,splay)的更多相关文章
- BZOJ2816:[ZJOI2012]网络(LCT)
Description 有一个无向图G,每个点有个权值,每条边有一个颜色.这个无向图满足以下两个条件: 对于任意节点连出去的边中,相同颜色的边不超过两条. 图中不存在同色的环,同色的环指相同颜色的边构 ...
- bzoj 2816: [ZJOI2012]网络 (LCT 建多棵树)
链接:https://www.lydsy.com/JudgeOnline/problem.php?id=2816 题面: http://www.lydsy.com/JudgeOnline/upload ...
- bzoj2816 [ZJOI2012]网络
Description http://www.lydsy.com/JudgeOnline/upload/zjoi2012.pdf 正解:$link-cut \ tree$. $LCT$板子题,直接维护 ...
- BZOJ.2816.[ZJOI2012]网络(LCT)
题目链接 BZOJ 洛谷 对每种颜色维护一个LCT,保存点之间的连接关系. 修改权值A[x]和所有Max[x]都要改: 修改边的颜色先枚举所有颜色,看是否在某种颜色中有边,然后断开.(枚举一遍就行啊 ...
- Luogu 2173 [ZJOI2012]网络 - LCT
Solution $LCT$ 直接上$QuQ$ 注意$cut$ 完 需要 $d[u + c * N]--$ 再 $link$, 不然会输出Error 1的哦 Code #include<cs ...
- bzoj千题计划223:bzoj2816: [ZJOI2012]网络
http://www.lydsy.com/JudgeOnline/problem.php?id=2816 每种颜色搞一个LCT 判断u v之间有边直接相连: 如果u和v之间有边相连,那么他们的深度相差 ...
- ZJOI2012 网络——LCT相关题目
有一个无向图G,每个点有个权值,每条边有一个颜色.这个无向图满足以下两个条件: 对于任意节点连出去的边中,相同颜色的边不超过两条. 图中不存在同色的环,同色的环指相同颜色的边构成的环. 在这个图上,你 ...
- luoguP2173 [ZJOI2012]网络 LCT
链接 luogu 思路 颜色很少,开10个lct分别维护 if (Hash.count(make_pair(u, v)) && Hash[make_pair(u, v)] == col ...
- bzoj 2816: [ZJOI2012]网络(splay)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2816 [题意] 给定一个无向图,满足条件:从一个节点出发的同色边不超过2条,且不存在同 ...
随机推荐
- C#自省
[C#自省] 1.根据string,获取type.Type.GetType 方法,获取具有指定名称的 Type,执行区分大小写的搜索. 2.根据obj,获取type.Object.GetType 方法 ...
- cdoj915-方老师的分身 II (长度不小于k的最短路)【spfa】
http://acm.uestc.edu.cn/#/problem/show/915 方老师的分身 II Time Limit: 10000/5000MS (Java/Others) Memo ...
- 146. LRU Cache (List, HashTable)
Design and implement a data structure for Least Recently Used (LRU) cache. It should support the fol ...
- 为什么3D模型的网格由很多三角形来组成
因为二点确定一条线,三点确定一个面 网格就是由很多面组成的,四个点也能组成面 但是三个点就足够了
- EXADATA智能扫描
提要:查询特定的要求:智能扫描只可用于完整的表或索引扫描.智能扫描只能用于直接路径读取: 直接路径读取会自动用于并行查询. 直接路径读取可以用于串行查询.默认情况下不使用它们进行小型表的串行扫描.使用 ...
- ActiveMQ 使用文档
一.为什么使用ActiveMQ 在总线的设计中可能会使用到JMS(Java Message Service)通道, Java消息服务(JMS)超越了生产商专有的MOM(Message-Oriented ...
- (转)Android SDK Manager国内无法更新的解决方案
转载地址:http://www.linuxidc.com/Linux/2015-01/111958.htm 现在由于GWF,google基本和咱们说咱见了,就给现在在做Android 或者想学习An ...
- 浅谈 js中parseInt函数的解析[转]
首先还是从很热门的实例parseInt("09")==0说起. parseInt(number,type)这个函数后面如果不跟第2个参数来表示进制的话,默认是10进制. 比如说pa ...
- XSS的原理分析与解剖(第二篇)[转]
0×01 前言: 上节(http://www.freebuf.com/articles/web/40520.html)已经说明了xss的原理及不同环境的构造方法.本期来说说XSS的分类及挖掘方法. 当 ...
- Spring思维导图(IOC篇)
写在前面 写过java的都知道:所有的对象都必须创建:或者说:使用对象之前必须先创建.而使用ioc之后,你就可以不再手动创建对象,而是从ioc容器中直接获取对象. 就好像我们无需考虑对象的销毁回收一样 ...