【BZOJ2816】【ZJOI2012】网络(Link-Cut Tree)

题面

题目描述

有一个无向图G,每个点有个权值,每条边有一个颜色。这个无向图满足以下两个条件:

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

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

在这个图上,你要支持以下三种操作:

修改一个节点的权值。

修改一条边的颜色。

查询由颜色c的边构成的图中,所有可能在节点u到节点v之间的简单路径上的节点的权值的最大值。

输入输出格式

输入格式:

输入文件network.in的第一行包含四个正整数N, M, C, K,其中N为节点个数,M为边数,C为边的颜色数,K为操作数。

接下来N行,每行一个正整数vi,为节点i的权值。

之后M行,每行三个正整数u, v, w,为一条连接节点u和节点v的边,颜色为w。满足1 ≤ u, v ≤ N,0 ≤ w < C,保证u ≠ v,且任意两个节点之间最多存在一条边(无论颜色)。

最后K行,每行表示一个操作。每行的第一个整数k表示操作类型。

k = 0为修改节点权值操作,之后两个正整数x和y,表示将节点x的权值vx修改为y。

k = 1为修改边的颜色操作,之后三个正整数u, v和w,表示将连接节点u和节点v的边的颜色修改为颜色w。满足0 ≤ w < C。

k = 2为查询操作,之后三个正整数c, u和v,表示查询所有可能在节点u到节点v之间的由颜色c构成的简单路径上的节点的权值的最大值。如果不存在u和v之间不存在由颜色c构成的路径,那么输出“-1”。

输出格式:

输出文件network.out包含若干行,每行输出一个对应的信息。

对于修改节点权值操作,不需要输出信息。

对于修改边的颜色操作,按以下几类输出:

a) 若不存在连接节点u和节点v的边,输出“No such edge.”。

b) 若修改后不满足条件1,不修改边的颜色,并输出“Error 1.”。

c) 若修改后不满足条件2,不修改边的颜色,并输出“Error 2.”。

d) 其他情况,成功修改边的颜色,并输出“Success.”。

输出满足条件的第一条信息即可,即若同时满足b和c,则只需要输出“Error 1.”。

对于查询操作,直接输出一个整数。

输入输出样例

输入样例#1:

4 5 2 7

1

2

3

4

1 2 0

1 3 1

2 3 0

2 4 1

3 4 0

2 0 1 4

1 1 2 1

1 4 3 1

2 0 1 4

1 2 3 1

0 2 5

2 1 1 4

输出样例#1:

4

Success.

Error 2.

-1

Error 1.

5

题解

考虑\(C<=10\)

那么, 暴力维护\(C\)棵树即可

直接\(LCT\)维护即可

细节真的是有点多。。。

这道题目慢慢做。。。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define MAX 11000
#define fat t[x].ff
#define lson t[x].ch[0]
#define rson t[x].ch[1]
inline int read()
{
int x=0,t=1;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=-1,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return x*t;
}
int S[MAX],top;
struct N{int u,v;};
int n,m,C,K,val[MAX];
int color[MAX][11];
bool operator<(N a,N b)
{
if(a.u!=b.u)return a.u<b.u;
return a.v<b.v;
}
map<N,int> MM;
struct Node
{
int ch[2],ff;
int mm,val,rev;
};
struct LCT
{
struct Node t[MAX];
void pushup(int x){t[x].mm=max(t[lson].mm,t[rson].mm);t[x].mm=max(t[x].mm,t[x].val);}
bool isroot(int x){return t[fat].ch[0]!=x&&t[fat].ch[1]!=x;}
void pushdown(int x)
{
if(!t[x].rev)return;
swap(lson,rson);
t[lson].rev^=1;t[rson].rev^=1;
t[x].rev^=1;
}
void rotate(int x)
{
int y=t[x].ff,z=t[y].ff;
int k=t[y].ch[1]==x;
if(!isroot(y))t[z].ch[t[z].ch[1]==y]=x;t[x].ff=z;
t[y].ch[k]=t[x].ch[k^1];t[t[x].ch[k^1]].ff=y;
t[x].ch[k^1]=y;t[y].ff=x;
pushup(y);pushup(x);
}
void Splay(int x)
{
S[top=1]=x;
for(int i=x;!isroot(i);i=t[i].ff)S[++top]=t[i].ff;
while(top)pushdown(S[top--]);
while(!isroot(x))
{
int y=t[x].ff,z=t[y].ff;
if(!isroot(y))
(t[y].ch[0]==x)^(t[z].ch[0]==y)?rotate(x):rotate(y);
rotate(x);
}
}
void access(int x){for(int y=0;x;y=x,x=t[x].ff)Splay(x),t[x].ch[1]=y,pushup(x);}
void makeroot(int x){access(x);Splay(x);t[x].rev^=1;}
void split(int x,int y){makeroot(x);access(y);Splay(y);}
void cut(int x,int y){split(x,y);t[y].ch[0]=t[x].ff=0;}
void link(int x,int y){makeroot(x);t[x].ff=y;}
int findroot(int x){access(x);Splay(x);while(lson)x=lson;return x;}
}LCT[11];
int main()
{
n=read();m=read();C=read();K=read();
for(int i=1;i<=n;++i)val[i]=read();
for(int i=1;i<=n;++i)
for(int j=1;j<=C;++j)
LCT[j].t[i].val=val[i];
for(int i=1,u,v,w;i<=m;++i)
{
u=read(),v=read(),w=read()+1;
MM[(N){u,v}]=w;
MM[(N){v,u}]=w;
color[u][w]++;color[v][w]++;
LCT[w].link(u,v);
}
while(K--)
{
int opt=read();
if(opt==0)
{
int x=read();val[x]=read();
for(int i=1;i<=C;++i)
{
LCT[i].access(x);
LCT[i].Splay(x);
LCT[i].t[x].val=val[x];
}
}
else if(opt==1)
{
int u=read(),v=read(),w=read()+1;
int G=MM[(N){u,v}];
if(!G){puts("No such edge.");continue;}
if(G==w){puts("Success.");continue;}
if(color[u][w]>1||color[v][w]>1){puts("Error 1.");continue;}
if(LCT[w].findroot(u)==LCT[w].findroot(v)){puts("Error 2.");continue;}
color[u][w]++;color[v][w]++;
color[u][G]--;color[v][G]--;
MM[(N){u,v}]=w;MM[(N){v,u}]=w;
LCT[G].cut(u,v);
LCT[w].link(u,v);
puts("Success.");
}
else
{
int w=read()+1,u=read(),v=read();
if(LCT[w].findroot(u)!=LCT[w].findroot(v)){puts("-1");continue;}
LCT[w].split(u,v);
printf("%d\n",LCT[w].t[v].mm);
}
}
return 0;
}

【BZOJ2816】【ZJOI2012】网络(Link-Cut Tree)的更多相关文章

  1. Link Cut Tree 总结

    Link-Cut-Tree Tags:数据结构 ##更好阅读体验:https://www.zybuluo.com/xzyxzy/note/1027479 一.概述 \(LCT\),动态树的一种,又可以 ...

  2. link cut tree 入门

    鉴于最近写bzoj还有51nod都出现写不动的现象,决定学习一波厉害的算法/数据结构. link cut tree:研究popoqqq那个神ppt. bzoj1036:维护access操作就可以了. ...

  3. Codeforces Round #339 (Div. 2) A. Link/Cut Tree 水题

    A. Link/Cut Tree 题目连接: http://www.codeforces.com/contest/614/problem/A Description Programmer Rostis ...

  4. Link/cut Tree

    Link/cut Tree 一棵link/cut tree是一种用以表示一个森林,一个有根树集合的数据结构.它提供以下操作: 向森林中加入一棵只有一个点的树. 将一个点及其子树从其所在的树上断开. 将 ...

  5. 洛谷P3690 Link Cut Tree (模板)

    Link Cut Tree 刚开始写了个指针版..调了一天然后放弃了.. 最后还是学了黄学长的板子!! #include <bits/stdc++.h> #define INF 0x3f3 ...

  6. LCT总结——概念篇+洛谷P3690[模板]Link Cut Tree(动态树)(LCT,Splay)

    为了优化体验(其实是强迫症),蒟蒻把总结拆成了两篇,方便不同学习阶段的Dalao们切换. LCT总结--应用篇戳这里 概念.性质简述 首先介绍一下链剖分的概念(感谢laofu的讲课) 链剖分,是指一类 ...

  7. bzoj2049 [Sdoi2008]Cave 洞穴勘测 link cut tree入门

    link cut tree入门题 首先说明本人只会写自底向上的数组版(都说了不写指针.不写自顶向下QAQ……) 突然发现link cut tree不难写... 说一下各个函数作用: bool isro ...

  8. P3690 【模板】Link Cut Tree (动态树)

    P3690 [模板]Link Cut Tree (动态树) 认父不认子的lct 注意:不 要 把 $fa[x]$和$nrt(x)$ 混 在 一 起 ! #include<cstdio> v ...

  9. Link Cut Tree学习笔记

    从这里开始 动态树问题和Link Cut Tree 一些定义 access操作 换根操作 link和cut操作 时间复杂度证明 Link Cut Tree维护链上信息 Link Cut Tree维护子 ...

  10. [CodeForces - 614A] A - Link/Cut Tree

    A - Link/Cut Tree Programmer Rostislav got seriously interested in the Link/Cut Tree data structure, ...

随机推荐

  1. 关于webconsole报../website/console.go:35: undefined: ssh.InsecureIgnoreHostkey 错误解决方案

    1.首先,进入webconsole目录删除/opt/webconsole/src/golang.org/x/目录下 crypto文件夹 2.然后,在/opt/webconsole/src/golang ...

  2. ubuntu下双网卡桥接

    1. 安装 brctl工具 sudo apt-get install bridge-utils 2. 添加桥 # brctl addbr br0 #创建桥接 br0 # brctl addif br0 ...

  3. [HEOI2016]求和 sum

    [HEOI2016]求和 sum 标签: NTT cdq分治 多项式求逆 第二类斯特林数 Description 求\[\sum_{i=0}^n\sum_{j=0}^i S(i,j)×2^j×(j!) ...

  4. 数组的toString方法

    数组继承了object类的toString方法,数据类型将按照旧的格式打印,例如: int[] luckyNumbers = {2,3,5,7,11,13}; String s = "&qu ...

  5. Windows Sublime Text 配置Linux子系统(WSL)下的 gcc/g++ 编译环境

    0. 简介(若已了解背景可以跳过此部分) Windows 10 Build 14316以上版本中加入了"Windows系统的Linux子系统"(Windows Subsystem ...

  6. 历届试题 剪格子 IDA*

    思路:限制当前能剪下的最大格子数,保证能得到最少数目.IDA*的典型运用. AC代码 #include <cstdio> #include <cmath> #include & ...

  7. 算法提高 拿糖果 线性DP

    题目链接:拿糖果 思路:首先给小于根号n的素数打表.d(i)表示当前剩余i颗糖,最多可以拿到多少糖.     转移方程:d(i) = max(d(i), k + d(i - 2 * k)),此处k表示 ...

  8. Service IP 原理 - 每天5分钟玩转 Docker 容器技术(137)

    Service Cluster IP 是一个虚拟 IP,是由 Kubernetes 节点上的 iptables 规则管理的. 可以通过 iptables-save 命令打印出当前节点的 iptable ...

  9. 网站入住各大搜索引擎的seo优化技巧

    最近在公司上班的时候做了一个工业物联网的项目,上层主管提出要求,让这个网站入住各大搜索引擎,也就是说在各大搜索引擎中输入与网站相关的关键字就能搜索到我们自己的网站.刚开始自己一脸懵逼,因为之前自己并没 ...

  10. Spring+SpringMVC+MyBatis+easyUI整合进阶篇(十四)Redis缓存正确的使用姿势

    作者:13 GitHub:https://github.com/ZHENFENG13 版权声明:本文为原创文章,未经允许不得转载. 简介 这是一篇关于Redis使用的总结类型文章,会先简单的谈一下缓存 ...