[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条,且不存在同 ...
随机推荐
- Shaders
[Shaders] 1.Vertex-Lit,顶点光照着色器. Vertex-Lit is one of the simplest shaders. All lights shining on it ...
- Java方法重写与super关键字
----------siwuxie095 方法的重写: (1)在继承中也存在着重写的概念,其实就是子类定义了和父类同名的方法 (2)定义:方法名 ...
- ios-loadView
// 先判断当前控制器是不是从storyBoard中加载,如果是,就会加载stroyBoard的view // 判断是否是xib加载 // 否则创建一个空白的view // 如果重写了此方法, ...
- CGAffineTransformMake 矩阵变换 的运算原理(转)
1.矩阵的基本知识: struct CGAffineTransform { CGFloat a, b, c, d; CGFloat tx, ty; }; CGAffineTransform CGAff ...
- linux系统软件版本升级
在安装完软件之后,在同一层目录生成一个符号链接,并把当前软件的目录映射到这个链接上,后面的操作都只通过这个链接去做,以后升级版本的时候,把最新的软件目录映射到这个链接上就可以了. 如我刚装的apach ...
- CecOS Virtualization
CecOS CecOS 是 OPENFANS 为中小型企业提供企业开源云计算解决方案的基础框架:CecOSvt 是一款运行在社区企业云操作系统(CecOS)上的虚拟化开放式解决方案. 也可用演示模式. ...
- cs231n(一)
1.Nearest Neighbor Classifier 计算未分类数据(图片)与已标记类别的训练数据(training set)的距离(L1,L2等距离),然后返回与训练数据(图片)最小距离的图片 ...
- SVM之SMO算法(转)
支持向量机(Support Vector Machine)-----SVM之SMO算法(转) 此文转自两篇博文 有修改 序列最小优化算法(英语:Sequential minimal optimizat ...
- python nose的html报告优化
用的是nose的nose-html-reporting (0.2.3)插件生成报告.用了bootstrap前端框架,加入了开始时间和计算持续时间,及其本地化. 优化后的显示效果: 代码地址
- Qt的翻译文件QTranslator不能使用问题总结(原)
笔者今天在自己工程中使用翻译文件,发现没有起作用,反复查找,发现是用宏定义了命名空间,生成.ts文件时,不会加上命名空间,所以生成的.qm文件在实际使用时,会无法找到对应的语句. 如果将宏定义的命名空 ...