ZJOI2012 网络——LCT相关题目
有一个无向图G,每个点有个权值,每条边有一个颜色。这个无向图满足以下两个条件:
对于任意节点连出去的边中,相同颜色的边不超过两条。
- 图中不存在同色的环,同色的环指相同颜色的边构成的环。
在这个图上,你要支持以下三种操作:
修改一个节点的权值。
修改一条边的颜色。
- 查询由颜色c的边构成的图中,所有可能在节点u到节点v之间的简单路径上的节点的权值的最大值。
https://daniu.luogu.org/problem/show?pid=2173
-by luogu
对每个颜色建LCT,对error1数组记录,对error2LCT判联通性,对NO Such...直接写了hash,trie树大概开不下;
发现封装起来非常好;
代码:
#include<cstdio>
#include<cstring>
using namespace std;
int n,m,c,p;
struct dt{
int fa,ch[],mark,max,num;
};
struct LCT{
dt data[];
int tot;
void Init(){
data[].fa=data[].mark=data[].max=data[].max=data[].num=;
tot=;
}
void link(int x,int y){
make_root(x);data[x].fa=y;
}
void cut(int x,int y){
make_root(x),access(y),splay(y);
data[x].fa=data[y].ch[]=;
up(y);
}
void access(int x){
int y=;
while(x){
splay(x);
data[x].ch[]=y;
up(x);
y=x;x=data[x].fa;
}
}
void make_root(int x){
access(x);splay(x);data[x].mark^=;
}
int find_root(int x){
access(x);splay(x);
while(data[x].ch[])
x=data[x].ch[];
return x;
}
void splay(int x){
push(x);
int fa,fafa;
for(fa=data[x].fa;data[fa].ch[]==x||data[fa].ch[]==x;roll(x),fa=data[x].fa){
fafa=data[fa].fa;
if(data[fafa].ch[]==fa||data[fafa].ch[]==fa)
if((data[fa].ch[]==x)^(data[fafa].ch[]==fa))
roll(x);
else
roll(fa);
}
}
void roll(int now){
int fa=data[now].fa,fafa=data[fa].fa,wh=data[fa].ch[]==now;
data[fa].ch[wh]=data[now].ch[wh^];data[data[fa].ch[wh]].fa=fa;
data[now].ch[wh^]=fa;data[fa].fa=now;
data[now].fa=fafa;
if (data[fafa].ch[]==fa||data[fafa].ch[]==fa)
data[fafa].ch[data[fafa].ch[]==fa]=now;
up(fa);up(now);
}
void push(int x){
int fa=data[x].fa;
if(data[fa].ch[]==x||data[fa].ch[]==x)
push(fa);
down(x);
}
void up(int x){
int a=data[data[x].ch[]].max>data[data[x].ch[]].max?data[data[x].ch[]].max:data[data[x].ch[]].max;
data[x].max=data[x].num>a?data[x].num:a;
}
void down(int x){
int i;
if(data[x].mark){
i=data[x].ch[],data[x].ch[]=data[x].ch[],data[x].ch[]=i;
data[x].mark=;
data[data[x].ch[]].mark^=;data[data[x].ch[]].mark^=;
}
}
};
int Hash(int ,int ,int );
LCT lct[];
int col[][];
int hash[];
int poll[],next[],colway[],tot;
int main()
{
int i,j,k,u,v,w;
scanf("%d%d%d%d",&n,&m,&c,&p);
for(j=;j<c;j++)lct[j].Init();
for(i=;i<=n;i++){
scanf("%d",&k);
for(j=;j<c;j++)
lct[j].data[i].num=lct[j].data[i].max=k;
}
for(i=;i<=m;i++){
scanf("%d%d%d",&u,&v,&w);
lct[w].link(u,v);
col[u][w]++;col[v][w]++;
Hash(u*+v,,w),Hash(v*+u,,w);
}
for(i=;i<=p;i++){
scanf("%d",&j);
if(j==){
scanf("%d%d",&u,&v);
for(k=;k<c;k++){
lct[k].splay(u);
lct[k].data[u].num=v;
lct[k].up(u);
}
continue;
}
if(j==){
int lk;
scanf("%d%d%d",&u,&v,&k);
lk=Hash(u*+v,,-);
if(!lk){
printf("No such edge.\n");continue;
}
if(--lk==k){
printf("Success.\n");continue;
}
if(col[u][k]==||col[v][k]==){
printf("Error 1.\n");continue;
}
lct[k].make_root(u);
if(lct[k].find_root(v)==u){
printf("Error 2.\n");continue;
}
lct[lk].cut(u,v);
lct[k].link(u,v);
col[u][lk]--;col[v][lk]--;col[u][k]++;col[v][k]++;
Hash(u*+v,,k);Hash(v*+u,,k);
printf("Success.\n");continue;
}
if(j==){
scanf("%d%d%d",&k,&u,&v);
lct[k].make_root(u);
if(lct[k].find_root(v)!=u){
printf("-1\n");continue;
}
lct[k].access(v);
lct[k].splay(v);
printf("%d\n",lct[k].data[v].max);
continue;
}
}
return ;
}
int Hash(int sum,int p,int color){
int mod=,x=sum%mod,i;
if(!hash[x]){
if(!p)return ;
hash[x]=++tot;
poll[tot]=sum;colway[tot]=color;
}
else{
i=hash[x];
while(next[i]&&poll[i]!=sum)
i=next[i];
if(p){
next[i]=++tot;
poll[tot]=sum;
colway[tot]=color;
return ;
}
if(poll[i]!=sum)return ;
if(color==-)return colway[i]+;
colway[i]=color;
}
return ;
}
ZJOI2012 网络——LCT相关题目的更多相关文章
- bzoj 2816: [ZJOI2012]网络 (LCT 建多棵树)
链接:https://www.lydsy.com/JudgeOnline/problem.php?id=2816 题面: http://www.lydsy.com/JudgeOnline/upload ...
- 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 ...
- BZOJ2816:[ZJOI2012]网络(LCT)
Description 有一个无向图G,每个点有个权值,每条边有一个颜色.这个无向图满足以下两个条件: 对于任意节点连出去的边中,相同颜色的边不超过两条. 图中不存在同色的环,同色的环指相同颜色的边构 ...
- luoguP2173 [ZJOI2012]网络 LCT
链接 luogu 思路 颜色很少,开10个lct分别维护 if (Hash.count(make_pair(u, v)) && Hash[make_pair(u, v)] == col ...
- 洛谷 P2173 [ZJOI2012]网络 解题报告
P2173 [ZJOI2012]网络 题目描述 有一个无向图G,每个点有个权值,每条边有一个颜色.这个无向图满足以下两个条件: 对于任意节点连出去的边中,相同颜色的边不超过两条. 图中不存在同色的环, ...
- linux网络配置相关命令、虚拟网络接口eth0:0
网络接口(interface)是网络硬件设备在操作系统中的表示方法,比如网卡在Linux操作系统中用ethX,是由0开始的正整数,比如eth0.eth1...... ethX.而普通猫和ADSL的接口 ...
- Linux网络配置相关
路由相关 #添加到主机的路由 route add -host 192.168.1.2 dev eth0 route add -host 192.168.1.2 gw 192.168.1.1 注1:添加 ...
- linux网络配置相关文件
网络接口(interface)是网络硬件设备在操作系统中的表示方法,比如网卡在Linux操作系统中用ethX,是由0开始的正整数,比如eth0.eth1...... ethX.而普通猫和ADSL的接口 ...
随机推荐
- Welcome! This is the documentation for Python 3.6.8
The Zen of Python, by Tim Peters Beautiful is better than ugly.Explicit is better than implicit.Simp ...
- 基础概念——令人迷惑的EOF
EOF概念常常使人迷惑. 首先我们要理解并没有像EOF字符这样的东西. 进一步讲EOF是由内核检测到的一种条件. 应用程序在它接收到由read函数返回的零返回码时,它就会发现EOF条件. 对于磁盘文件 ...
- MAVEN打zip包
https://blog.csdn.net/yulin_hu/article/details/81835945 https://www.cnblogs.com/f-zhao/p/6929814.htm ...
- io流之节点流inputstream、outputstream、reader、writer
例子程序:读取工作空间下 package io; import java.io.*; public class TestFileInputStream { public static void mai ...
- 002javascript变量&数据类型
•变量 –JavaScript 是一种弱类型的脚本语言 –var c = 3:即变量的声明(变量使用之前必须加var声明,编程规范) –变量的命名规则! •1.变量命名必须以字母或是下标符号”_”或者 ...
- 从setTimeout谈js运行机制
众所周知,JavaScript是单线程的编程,什么是单线程,就是说同一时间JavaScript只能执行一段代码,如果这段代码要执行很长时间,那么之后的代码只能尽情地等待它执行完才能有机会执行,不像人一 ...
- Javac的命令(-Xlint)
在OptionName类中的枚举定义如下: XLINT("-Xlint"), XLINT_CUSTOM("-Xlint:"), -Xlint Enabl ...
- python-TCP模拟ftp文件传输
#!/usr/bin/python #coding=utf-8 #server from socket import* import sys,os def command(): l=[ "W ...
- JavaScript引擎理解
JavaScript 虽然给人感觉是一个多线程执行的语言,但是其实JavaScript引擎是伪多线程,是单线程执行的, 浏览器内核:实现允许多个线程异步执行,这些线程在内核制控下相互配合以保持同步.假 ...
- [转载]二叉树(BST,AVT,RBT)
二叉查找树(Binary Search Tree)是满足如下性质的二叉树:①若它的左子树非空,则左子树上所有结点的值均小于根结点的值:②若它的右子树非空,则右子树上所有结点的值均大于根结点的值:③左. ...