[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条,且不存在同 ...
随机推荐
- Linux实战教学笔记28:企业级LNMP环境应用实践
一,LNMP应用环境 1.1 LNMP介绍 大约在2010年以前,互联网公司最常用的经典Web服务环境组合就是LAMP(即Linux,Apache,MySQL,PHP),近几年随着Nginx Web服 ...
- Python_11-正则表达式
目录: 1.1 引言 1.2 python 正则式概述及常用字符 1.2.1 元字符 1.2.2 用 "" 开始的特殊字符所表示的预定义 ...
- 高性能Web服务器Nginx的配置与部署研究(14)平滑升级你的Nginx
1.概述(可以直接跳过看第2部分) Nginx方便地帮助我们实现了平滑升级.其原理简单概括,就是: (1)在不停掉老进程的情况下,启动新进程. (2)老进程负责处理仍然没有处理完的请求,但不再接受处理 ...
- Spring Data Jpa使用@Query注解实现模糊查询(LIKE关键字)
/** * * @param file_name 传入参数 * @return */ @Query(value = "select * from user where name LIKE C ...
- Maven01 环境准备、maven项目结构、编译/测试/打包/清除、安装、
0 前提准备 0.1 安装java开发环境 0.2 安装maven工具 1 maven项目基本结构 如图所示,整个maven项目有业务文件.测试文件.POM依赖管理文件:其实还有一个资源文件resou ...
- 4418开发板读取u盘说明
1.插上u盘后会在dev下生成两个文件db db1 将db1挂载即可访问..
- [C++ Mind Map] class and memory
class and memory
- Python 解析配置模块之ConfigParser详解-乾颐堂
1.基本的读取配置文件 -read(filename) 直接读取ini文件内容 -sections() 得到所有的section,并以列表的形式返回 -options(section) 得到该sect ...
- name相同获取值
<html> <head> </head> <body> <form name="form1" method="po ...
- class Qstring has no member named to Ascii
人家修改了.真的没有toAscii了.不过可以用toLatin1或者qPrintable()