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的接口 ...
随机推荐
- LLDB 和Chisel 使用例子
打印变量 打印数字 (lldb) p/d 16 16 16 进制格式 (lldb) p/x 16 0x10 2 进制格式 (lldb) p/t 16 0b00000000000000000000000 ...
- mysql导入大批量数据出现MySQL server has gone away的解决方法
因工作需要,需要导入一个200M左右的sql到user库 执行命令 mysql> use user Database changed mysql> source /tmp/user.sql ...
- pixi.js v5版本出了。
历尽千辛万苦,pixi.js v5版本出了. 请关注群 881784250, 会尽块出个微信小游戏版. pixi.js的每个函数,每个类都有测试用例的.出的版本都是很稳定的.
- github常用项目汇总
1.smartTable(智能表格) android自动生成表格框架 使用方法:在github中搜索smartTable 进入项目后,查看开源项目的介绍和使用方法即可.
- 并发编程>>概念准备(一)
工于其善,必先利器 1.并发和并行的区别 并行:同一时间点执行多个任务(CPU多核或多个CPU同时执行多个任务) 并发:同一时间段内行多个任务(单核同时执行多个任务) 2.同步和异步的区别 同步:执行 ...
- 解决TeamViewer无法按给定网络地址联系伙伴
说明:这种现象一般是断网后DNS改变了,或者路由重启了没有重启网络配合导致的. 解决方法: 1.Windows: ipconfig /flushdns 2.Linux: /etc/rc.d/init. ...
- redis的key
Redis支持的数据模型: Redis支持的数据类型: redis的key: Redis对key的操作: 执行命令cd /usr/local/redis进入到redis的启动目录,执行./redis ...
- thinkPHP5配置nginx环境无法打开(require(): open_basedir restriction in effect. File(/mnt/hgfs/root/tp5/thinkphp/start.php) is not within the allowed path(s)
今天想把玩一下tp5,结果怎么都无法访问,每次都是报500错误,我把错误提示都打开看到下面的错误 require(): open_basedir restriction in effect. File ...
- python-poll实现异步IO
#!usr/bin/python from socket import * from select import * from time import ctime s=socket() s.bind( ...
- python中的生成器(一)
我们先考虑一个场景: 有个情景需要循环输出1——10. 这里给两种方法: list1 = [1,2,3,4,5,6,7,8,9,10] for i in list1: print(i) for i i ...