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的接口 ...
随机推荐
- 二手前端入门React项目
个人对ReactJS这门技术比较感兴趣,在基友的帮助下成功创建了一个React标准前端工程,过程中遇到了不少麻烦,今天作为笔记一般记录一下遇到的问题和解决方案. 基础环境 手头一台Mac 使用OSX系 ...
- java程序向hdfs中追加数据,异常以及解决方案
今天在学习hdfs时,遇到问题,就是在向hdfs中追加数据总是报错,在经过好几个小时的努力之下终于将他搞定 解决方案如下:在hadoop的hdfs-sit.xml中添加一下三项 <propert ...
- Cause: org.jetbrains.plugins.gradle.tooling.util.ModuleComponentIdentifierIm Lorg/gradle/api/artifacts/ModuleIdentifier;
今天碰到一个问题, 正常的下载gradle到本地,然后到spring官网上通过他们提供的start.spring.io创建一个demo项目, 然后在idea中打开,并配置下载的gradle到idea中 ...
- CODEVS-新斯诺克
原题地址:新斯诺克 题目描述 Description 斯诺克又称英式台球,是一种流行的台球运动.在球桌上,台面四角以及两长边中心位置各有一个球洞,使用的球分别为1 个白球,15 个红球和6 个彩球(黄 ...
- P4859 已经没有什么好害怕的了
传送门 见计数想容斥 首先题目可以简单转化一下, 求 糖果比药片能量大的组数比药片比糖果能量大的组数多 $k$ 组 的方案数 因为所有能量各不相同,所以就相当于求 糖果比药片能量大的组数为 $(n+k ...
- 等价类计数问题(Polya定理和burnside引理)
零.约定: (置换等名词会在前置知识中有解释) \(1.\)在本文中,题目要求的染色方案等统称为"元素". \(2.\)两个元素严格相等我们记做"\(=\)", ...
- java翻译到mono C#实现系列(3) 获取手机设备信息(残缺,)
using System; using Android.App; using Android.Content; using Android.Runtime; using Android.Views; ...
- [Xamarin.Android] 如何使用Google Map V2 (转帖)
Google Map v1已經在2013年的3月開始停止支援了,目前若要在你的Android手機上使用到Google Map,就必須要使用 到Google Map v2的版本.在Xamarin要使用G ...
- 解决UnicodeDecodeError: 'ascii' code can't decode byte 0xef in position
今天在使用python的pip安装的时候出现了这个错误 UnicodeDecodeError: 'ascii' code can't decode byte 0xef in position 7: o ...
- Javac之inner与nested类
One way declared types in Java differ from one another is whether the type is a class (which include ...