洛谷P2173 [ZJOI2012]网络(10棵lct与瞎jb暴力)
有一个无向图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.”。
- 对于查询操作,直接输出一个整数。
输入输出样例
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
4
Success.
Error 2.
-1
Error 1.
5 题解:这题写了两个小时才A掉,估计没人比我更菜了
这题的语文要求还有点小高,我们一个一个来分析
首先看到颜色个数很少,而且颜色会变,不难想到对每种颜色搞一颗lct
那么第一个操作权值修改就是将每颗lct里的x rotate到当前splay的根,接着更新权值。
第二个操作比较繁琐
首先是没边的情况,因为题目保证了每个点相同颜色的边不超过两条,所以每个点最多有20条边,这样可以暴力遍历每一条边,查找是不是存在x到y的边。
接着是边数超过两条的情况,很显然还是暴力搜每一条边,如果x和y两点有一点已经连接了两个该颜色,那就GG了
接着是是否已经联通的问题,显然make_root然后find_root一下就可以了
最后就是把原来颜色的lct里cut一下,现在lct里link一下就行了。
第三个操作中规中矩
就是splay里push_up一下,把x splay到根,接着输出答案就行了。 最大的坑点——可能x到y的边被更新成原来的颜色,这样子操作二的第二种情况就会出锅,所以要优先处理一下, 代码如下:
#include<map>
#include<set>
#include<queue>
#include<cmath>
#include<cstdio>
#include<string>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
#define N 10010
#define mp make_pair
#define lson ch[x][0]
#define rson ch[x][1]
#define pii pair<int,int>
using namespace std; int w[N]; struct lct
{
int sum[N],f[N],ch[N][],tag[N]; int not_root(int now)
{
int x=f[now];
return lson==now||rson==now;
} int push_up(int x)
{
sum[x]=max(max(sum[lson],sum[rson]),w[x]);
} int rev(int x)
{
swap(lson,rson);
tag[x]^=;
} int push_down(int x)
{
if(tag[x])
{
rev(lson);
rev(rson);
tag[x]^=;
}
} int rotate(int x)
{
int y=f[x],z=f[y],kd=ch[y][]==x,xs=ch[x][!kd];
if(not_root(y))
{
ch[z][ch[z][]==y]=x;
}
ch[x][!kd]=y;
ch[y][kd]=xs;
if(xs) f[xs]=y;
f[y]=x;
f[x]=z;
push_up(y);
} int push_all(int x)
{
if(not_root(x))
{
push_all(f[x]);
}
push_down(x);
} int splay(int x)
{
int y,z;
push_all(x);
while(not_root(x))
{
y=f[x],z=f[y];
if(not_root(y))
{
(ch[y][]==x)^(ch[z][]==y)?rotate(x):rotate(y);
}
rotate(x);
}
push_up(x);
} int access(int x)
{
for(int y=; x; y=x,x=f[x])
{
splay(x);
rson=y;
push_up(x);
}
} int make_root(int x)
{
access(x);
splay(x);
rev(x);
} int split(int x,int y)
{
make_root(x);
access(y);
splay(y);
} int find_root(int x)
{
access(x);
splay(x);
while(lson)
{
push_down(x);
x=lson;
}
return x;
} int link(int x,int y)
{
make_root(x);
if(find_root(y)==x) return ;
f[x]=y;
return ;
} int cut(int x,int y)
{
make_root(x);
if(find_root(y)!=x||f[x]!=y||rson) return ;
f[x]=ch[y][]=;
return ;
}
int print(int x)
{
if(lson) print(lson);
printf("%d ",x);
if(rson) print(rson);
}
} tr[]; vector<pii> g[];
int n,m,c,k; int main()
{
scanf("%d%d%d%d",&n,&m,&c,&k);
for(int i=; i<=n; i++)
{
scanf("%d",&w[i]);
}
int from,to,cl;
for(int i=; i<=m; i++)
{
scanf("%d%d%d",&from,&to,&cl);
tr[cl].link(from,to);
g[from].push_back(mp(to,cl));
g[to].push_back(mp(from,cl));
}
while(k--)
{
int kd,x,y,cc;
scanf("%d",&kd);
if(kd==)
{
scanf("%d%d",&x,&y);
for(int i=; i<c; i++)
{
tr[i].splay(x);
}
w[x]=y;
}
if(kd==)
{
int flag=,tot=,tot2=,pos;
scanf("%d%d%d",&x,&y,&cc);
for(int i=; i<g[x].size(); i++)
{
if(g[x][i].first==y)
{
flag=;
pos=g[x][i].second;
}
if(g[x][i].second==cc)
{
tot++;
}
}
for(int i=; i<g[y].size(); i++)
{
if(g[y][i].second==cc)
{
tot2++;
}
}
tot=max(tot2,tot);
if(flag)
{
puts("No such edge.");
continue;
}
if(pos==cc)
{
puts("Success.");
continue;
}
if(tot==)
{
puts("Error 1.");
continue;
}
tr[cc].make_root(x);
if(tr[cc].find_root(y)==x)
{
puts("Error 2.");
continue;
}
tr[pos].cut(x,y);
tr[cc].link(x,y);
for(int i=; i<g[x].size(); i++)
{
if(g[x][i].first==y)
{
g[x][i].second=cc;
break;
}
}
for(int i=; i<g[y].size(); i++)
{
if(g[y][i].first==x)
{
g[y][i].second=cc;
break;
}
}
puts("Success.");
}
if(kd==)
{
scanf("%d%d%d",&cc,&x,&y);
tr[cc].make_root(x);
if(tr[cc].find_root(y)!=x)
{
puts("-1");
continue;
}
printf("%d\n",tr[cc].sum[y]);
}
}
}
洛谷P2173 [ZJOI2012]网络(10棵lct与瞎jb暴力)的更多相关文章
- 洛谷 P2173 [ZJOI2012]网络 解题报告
P2173 [ZJOI2012]网络 题目描述 有一个无向图G,每个点有个权值,每条边有一个颜色.这个无向图满足以下两个条件: 对于任意节点连出去的边中,相同颜色的边不超过两条. 图中不存在同色的环, ...
- 洛谷 P1546 最短网络 Agri-Net
题目链接 https://www.luogu.org/problemnew/show/P1546 题目背景 农民约翰被选为他们镇的镇长!他其中一个竞选承诺就是在镇上建立起互联网,并连接到所有的农场.当 ...
- 洛谷P1546 最短网络 Agri-Net(最小生成树,Kruskal)
洛谷P1546 最短网络 Agri-Net 最小生成树模板题. 直接使用 Kruskal 求解. 复杂度为 \(O(E\log E)\) . #include<stdio.h> #incl ...
- 洛谷U19464 山村游历(Wander)(LCT,Splay)
洛谷题目传送门 LCT维护子树信息常见套路详见我的总结 闲话 题目摘自WC模拟试题(by Philipsweng),原题目名Wander,"山村游历"是自己搞出来的中文名. 数据自 ...
- 洛谷P3348 [ZJOI2016]大森林(LCT,虚点,树上差分)
洛谷题目传送门 思路分析 最简单粗暴的想法,肯定是大力LCT,每个树都来一遍link之类的操作啦(T飞就不说了) 考虑如何优化算法.如果没有1操作,肯定每个树都长一样.有了1操作,就来仔细分析一下对不 ...
- 洛谷U19464 山村游历(Wander)(LCT)
洛谷题目传送门 LCT维护子树信息常见套路详见我的总结 闲话 题目摘自WC模拟试题(by Philipsweng),原题目名Wander,"山村游历"是自己搞出来的中文名. 数据自 ...
- [洛谷P2597] [ZJOI2012]灾难
洛谷题目链接:[ZJOI2012]灾难 题目描述 阿米巴是小强的好朋友. 阿米巴和小强在草原上捉蚂蚱.小强突然想,如果蚂蚱被他们捉灭绝了,那么吃蚂蚱的小鸟就会饿死,而捕食小鸟的猛禽也会跟着灭绝,从而引 ...
- 洛谷P4332 [SHOI2014]三叉神经树(LCT,树剖,二分查找,拓扑排序)
洛谷题目传送门 你谷无题解于是来补一发 随便百度题解,发现了不少诸如树剖\(log^3\)LCT\(log^2\)的可怕描述...... 于是来想想怎么利用题目的性质,把复杂度降下来. 首先,每个点的 ...
- 洛谷P3613 睡觉困难综合征(LCT,贪心)
洛谷题目传送门 膜拜神犇出题人管理员!!膜拜yler和ZSY!! 没错yler连续教我这个蒟蒻写起床困难综合症和睡觉困难综合症%%%Orz,所以按位贪心的思路可以继承下来 这里最好还是写树剖吧,不过我 ...
随机推荐
- 灾难恢复:RPO与RTO
许多企事业单位虽然已经认识到信息安全的重要性,却迟迟没有行动.其中的原因是多方面的,最主要的一个原因就是在如何建立容灾系统的问题上存在种种疑惑.容灾设计指标主要与容灾系统的数据恢复能力有关,最常见的设 ...
- C#:Json数据反序列化为Dictionary并根据关键字获取指定的值
转自曾是土木人原文 C#:Json数据反序列化为Dictionary并根据关键字获取指定的值 Json数据: { "dataSet": { "header": ...
- 跟着太白老师学python 10day 函数的动态参数 *args, **kwargs, 形参的位置顺序
1. *args 接收实参的位置参数, **kwargs接收实参的关键字参数 def func(*args, **kwargs): print(args, kwargs) func(1, 2, 3, ...
- shiro和Spring整合使用注解时没有执行realm的doGetAuthorizationInfo回调方法的解决(XML配置)
在使用Shiro框架进行项目整合时,使用注解在使用Shiro框架进行项目整合时,使用注解在使用Shiro框架进行项目整合时,使用注解@RequiresPermissions为方法提供是需要的权限,但是 ...
- linux/ubuntu 端口开放
在ubuntu下面开放端口好像主要有两种方法,一种是ubuntu自带的防火墙,一种是iptables,这里我们主要使用iptables.本文的系统版本为ubuntu14.04和ubuntu16.04 ...
- axis客户端循环访问webservice的时候只发送了几条数据就断开了的问题
原因 axis客户端访问webservice默认是使用http1.0版本的,这个版本的http不能保持长连接,应该换成http1.1版本 具体修改步骤: <?xml version=" ...
- 2018-2019第一学期Java助教心得
随着期末考试落下了帷幕,本学习也结束了回顾本学期的历程,对我影响最深的还是这学期很幸运的成为代老师的助教,这也是我第一次接触助教工作.刚开始的时候我心里也有很多的担心,怕自己胜任不了这份工作,但随着时 ...
- 使用Windows绘图合成多张图
[使用Windows绘图合成多张图] 1.点击图片右键选择打开方式→选择画图工具打开图片. 2.这时图片可以改变外框大小,将外框尽量弄大些. 3.点击编辑选中下拉菜单中的粘贴来源,选择需要增加进来的图 ...
- java基础强化——深入理解反射
目录 1.从Spring容器的核心谈起 2. 反射技术初探 2.1 什么是反射技术 2.2 类结构信息和java对象的映射 3 Class对象的获取及需要注意的地方 4. 运行时反射获取类的结构信息 ...
- 143. Reorder List(List)
Given a singly linked list L: L0→L1→…→Ln-1→Ln, reorder it to: L0→Ln→L1→Ln-1→L2→Ln-2→… You must do th ...