Luogu P2173 [ZJOI2012]网络
题意
写的比较清楚,我就不解释了。
\(\texttt{Data Range:}n\leq 10^4,m\leq 10^5,c\leq 10,k\leq 10^5\)
题解
注意到 \(c\) 的范围很小,而且把每种颜色的边抠出来发现是一个森林(准确的来说是每个连通块都是链),于是我们可以对每种颜色都开个 \(\texttt{LCT}\)。
然后这题就基本上是板子题了,但是这题细节很多,可能会花费你很多的调试时间。
有一个坑点就是当修改 \((u,v)\) 这条边的颜色的时候如果新的颜色等于原来的颜色无论怎样都是成功的,因为保证每一次操作后的图是满足性质的。
代码
#include<bits/stdc++.h>
using namespace std;
typedef int ll;
typedef long long int li;
const ll MAXN=2e5+51;
struct Edge{
ll to,prev,col;
};
Edge ed[MAXN<<1];
ll n,m,c,qcnt,tot,u,v,w,op,col;
ll deg[MAXN][10],last[MAXN];
inline ll read()
{
register ll num=0,neg=1;
register char ch=getchar();
while(!isdigit(ch)&&ch!='-')
{
ch=getchar();
}
if(ch=='-')
{
neg=-1;
ch=getchar();
}
while(isdigit(ch))
{
num=(num<<3)+(num<<1)+(ch-'0');
ch=getchar();
}
return num*neg;
}
namespace LCT{
struct Node{
ll fa,mx,val,rv,sz;
ll ch[2];
};
struct LinkCutTree{
Node nd[MAXN];
ll st[MAXN];
#define ls nd[x].ch[0]
#define rs nd[x].ch[1]
inline bool nroot(ll x)
{
return nd[nd[x].fa].ch[0]==x||nd[nd[x].fa].ch[1]==x;
}
inline void update(ll x)
{
nd[x].mx=max(max(nd[x].val,nd[ls].mx),nd[rs].mx);
}
inline void reverse(ll x)
{
swap(ls,rs),nd[x].rv^=1;
}
inline void spread(ll x)
{
if(nd[x].rv)
{
ls?reverse(ls):(void)(1),rs?reverse(rs):(void)(1);
nd[x].rv=0;
}
}
inline void rotate(ll x)
{
ll fa=nd[x].fa,gfa=nd[fa].fa;
ll dir=nd[fa].ch[1]==x,son=nd[x].ch[!dir];
if(nroot(fa))
{
nd[gfa].ch[nd[gfa].ch[1]==fa]=x;
}
nd[x].ch[!dir]=fa,nd[fa].ch[dir]=son;
if(son)
{
nd[son].fa=fa;
}
nd[fa].fa=x,nd[x].fa=gfa,update(fa);
}
inline void splay(ll x)
{
ll fa=x,gfa,cur=0;
st[++cur]=fa;
while(nroot(fa))
{
st[++cur]=fa=nd[fa].fa;
}
while(cur)
{
spread(st[cur--]);
}
while(nroot(x))
{
fa=nd[x].fa,gfa=nd[fa].fa;
if(nroot(fa))
{
rotate((nd[fa].ch[0]==x)^(nd[gfa].ch[0]==fa)?x:fa);
}
rotate(x);
}
update(x);
}
inline void access(ll x)
{
for(register int i=0;x;x=nd[i=x].fa)
{
splay(x),rs=i,update(x);
}
}
inline void makeRoot(ll x)
{
access(x),splay(x),reverse(x);
}
inline ll findRoot(ll x)
{
access(x),splay(x);
while(ls)
{
spread(x),x=ls;
}
return x;
}
inline void split(ll x,ll y)
{
makeRoot(x),access(y),splay(y);
}
inline void link(ll x,ll y)
{
makeRoot(x);
if(findRoot(y)!=x)
{
nd[x].fa=y;
}
}
inline void cut(ll x,ll y)
{
makeRoot(x);
if(findRoot(y)==x&&nd[x].fa==y&&!rs)
{
nd[x].fa=nd[y].ch[0]=0,update(y);
}
}
#undef ls
#undef rs
};
}
LCT::LinkCutTree lct[10];
inline void addEdge(ll from,ll to,ll col)
{
ed[++tot].prev=last[from];
ed[tot].to=to;
ed[tot].col=col;
last[from]=tot;
}
inline bool check(ll u,ll v,ll w)
{
ll col=-1;
for(register int i=last[u];i;i=ed[i].prev)
{
if(ed[i].to==v)
{
col=ed[i].col;
break;
}
}
if(col==-1)
{
return puts("No such edge."),0;
}
if(w==col)
{
return puts("Success."),1;
}
if(deg[u][w]==2||deg[v][w]==2)
{
return puts("Error 1."),0;
}
if(lct[w].findRoot(u)==lct[w].findRoot(v))
{
return puts("Error 2."),0;
}
return puts("Success."),1;
}
int main()
{
n=read(),m=read(),c=read(),qcnt=read();
for(register int i=1;i<=n;i++)
{
v=read();
for(register int j=0;j<c;j++)
{
lct[j].nd[i].val=v;
}
}
for(register int i=0;i<m;i++)
{
u=read(),v=read(),w=read(),lct[w].link(u,v);
deg[u][w]++,deg[v][w]++,addEdge(u,v,w),addEdge(v,u,w);
}
for(register int i=0;i<qcnt;i++)
{
op=read(),u=read(),v=read();
if(op==0)
{
for(register int j=0;j<c;j++)
{
lct[j].splay(u),lct[j].nd[u].val=v;
}
}
if(op==1)
{
if(check(u,v,w=read()))
{
for(register int j=last[u];j;j=ed[j].prev)
{
if(ed[j].to==v)
{
col=ed[j].col,ed[j].col=w;
break;
}
}
for(register int j=last[v];j;j=ed[j].prev)
{
if(ed[j].to==u)
{
ed[j].col=w;
break;
}
}
lct[col].cut(u,v),lct[w].link(u,v);
deg[u][col]--,deg[v][col]--,deg[u][w]++,deg[v][w]++;
}
}
if(op==2)
{
w=read(),swap(u,w);
if(lct[w].findRoot(u)!=lct[w].findRoot(v))
{
puts("-1");
continue;
}
lct[w].split(u,v),printf("%d\n",lct[w].nd[v].mx);
}
}
}
Luogu P2173 [ZJOI2012]网络的更多相关文章
- 洛谷 P2173 [ZJOI2012]网络 解题报告
P2173 [ZJOI2012]网络 题目描述 有一个无向图G,每个点有个权值,每条边有一个颜色.这个无向图满足以下两个条件: 对于任意节点连出去的边中,相同颜色的边不超过两条. 图中不存在同色的环, ...
- Luogu 2173 [ZJOI2012]网络 - LCT
Solution $LCT$ 直接上$QuQ$ 注意$cut$ 完 需要 $d[u + c * N]--$ 再 $link$, 不然会输出Error 1的哦 Code #include<cs ...
- 洛谷P2173 [ZJOI2012]网络(10棵lct与瞎jb暴力)
有一个无向图G,每个点有个权值,每条边有一个颜色.这个无向图满足以下两个条件: 对于任意节点连出去的边中,相同颜色的边不超过两条. 图中不存在同色的环,同色的环指相同颜色的边构成的环. 在这个图上,你 ...
- P2173 [ZJOI2012]网络
\(\color{#0066ff}{ 题目描述 }\) 有一个无向图G,每个点有个权值,每条边有一个颜色.这个无向图满足以下两个条件: 对于任意节点连出去的边中,相同颜色的边不超过两条. 图中不存在同 ...
- [Luogu 2604] ZJOI2010 网络扩容
[Luogu 2604] ZJOI2010 网络扩容 第一问直接最大流. 第二问,添加一遍带费用的边,边权 INF,超级源点连源点一条容量为 \(k\) 的边来限流,跑费用流. 大约是第一次用 nam ...
- BZOJ2816:[ZJOI2012]网络——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=2816 https://www.luogu.org/problemnew/show/P2173 有一 ...
- BZOJ 1834 Luogu P2604 [ZJOI2010]网络扩容 (最小费用最大流)
题目连接: (luogu) https://www.luogu.org/problemnew/show/P2604 (bzoj) https://www.lydsy.com/JudgeOnline/p ...
- 【Luogu P3376】网络最大流
Luogu P3376 最大流是网络流模型的一个基础问题. 网络流模型就是一种特殊的有向图. 概念: 源点:提供流的节点(入度为0),类比成为一个无限放水的水厂 汇点:接受流的节点(出度为0),类比成 ...
- bzoj 2816: [ZJOI2012]网络 (LCT 建多棵树)
链接:https://www.lydsy.com/JudgeOnline/problem.php?id=2816 题面: http://www.lydsy.com/JudgeOnline/upload ...
随机推荐
- Centos-显示目录或者目录下文件信息-ls
ls 显示指定目录信息或指定目录下文件和目录信息,后边不跟文件目录路径信息默认为当前工作目录 默认显示输出信息的总行数统计数 相关参数 -a 显示所有文件或子目录,包含隐藏文档 # linux中以 . ...
- mysql-11-DML
#DML语言 /* 数据操作语言 插入:insert 修改:update 删除:delete */ #一.插入语句 /* 语法: insert into 表名(列名...) values(新值...) ...
- Azure Cosmos DB (一) 入门介绍
一,引言 今天是国庆.中秋双节房价的第三天,今天抽时间分享一篇关于使用Azure 提供的一项NoSql 服务-----Azure Cosmos DB.就有人问了,我听说过 MongoDB.Redis ...
- windows10 + docker利用文件映射进行编程开发
0. 以安装swoole框架"easyswoole"举例,建议使用powershell或者cmder输入命令 1. 首先准备好window10专业版开启Hyper-V,然后下载 ...
- python使用xpath(超详细)
使用时先安装 lxml 包 开始使用 和beautifulsoup类似,首先我们需要得到一个文档树 把文本转换成一个文档树对象 from lxml import etree if __name__ = ...
- Jupyter 绘图怎么显示中文
1. 简单加2行代码即可. import matplotlib.pyplot as plt plt.rcParams['font.sans-serif'] = [u'SimHei'] plt.rcPa ...
- aptitude命令
命令 作用 aptitude update 更新可用的包列表 aptitude upgrade 升级可用的包 aptitude dist-upgrade 将系统升级到新的发行版 aptitude in ...
- 最新最最最简单的Snagit傻瓜式破解教程(带下载地址)
最新最最最简单的Snagit傻瓜式破解教程(带下载地址) 下载地址 直接滑至文章底部下载 软件介绍 一个非常著名的优秀屏幕.文本和视频捕获.编辑与转换软件.可以捕获Windows屏幕.DOS屏幕:RM ...
- java swing 按钮事件触发两次或者多次
按钮事件触发多次? 如果是JButton,八成是由于粗心,多次添加了监听事件 保持只添加一个监听事件就解决了~
- Java结构体系