有一个无向图G,每个点有个权值,每条边有一个颜色。这个无向图满足以下两个条件:

  1. 对于任意节点连出去的边中,相同颜色的边不超过两条。

  2. 图中不存在同色的环,同色的环指相同颜色的边构成的环。

在这个图上,你要支持以下三种操作:

  1. 修改一个节点的权值。

  2. 修改一条边的颜色。

  3. 查询由颜色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表示操作类型。

  1. k = 0为修改节点权值操作,之后两个正整数x和y,表示将节点x的权值vx修改为y。

  2. k = 1为修改边的颜色操作,之后三个正整数u, v和w,表示将连接节点u和节点v的边的颜色修改为颜色w。满足0 ≤ w < C。

  3. k = 2为查询操作,之后三个正整数c, u和v,表示查询所有可能在节点u到节点v之间的由颜色c构成的简单路径上的节点的权值的最大值。如果不存在u和v之间不存在由颜色c构成的路径,那么输出“-1”。

 

输出格式:

 

输出文件network.out包含若干行,每行输出一个对应的信息。

  1. 对于修改节点权值操作,不需要输出信息。

  2. 对于修改边的颜色操作,按以下几类输出:

a) 若不存在连接节点u和节点v的边,输出“No such edge.”。

b) 若修改后不满足条件1,不修改边的颜色,并输出“Error 1.”。

c) 若修改后不满足条件2,不修改边的颜色,并输出“Error 2.”。

d) 其他情况,成功修改边的颜色,并输出“Success.”。

输出满足条件的第一条信息即可,即若同时满足b和c,则只需要输出“Error 1.”。

  1. 对于查询操作,直接输出一个整数。

 

输入输出样例

输入样例#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
输出样例#1: 复制

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暴力)的更多相关文章

  1. 洛谷 P2173 [ZJOI2012]网络 解题报告

    P2173 [ZJOI2012]网络 题目描述 有一个无向图G,每个点有个权值,每条边有一个颜色.这个无向图满足以下两个条件: 对于任意节点连出去的边中,相同颜色的边不超过两条. 图中不存在同色的环, ...

  2. 洛谷 P1546 最短网络 Agri-Net

    题目链接 https://www.luogu.org/problemnew/show/P1546 题目背景 农民约翰被选为他们镇的镇长!他其中一个竞选承诺就是在镇上建立起互联网,并连接到所有的农场.当 ...

  3. 洛谷P1546 最短网络 Agri-Net(最小生成树,Kruskal)

    洛谷P1546 最短网络 Agri-Net 最小生成树模板题. 直接使用 Kruskal 求解. 复杂度为 \(O(E\log E)\) . #include<stdio.h> #incl ...

  4. 洛谷U19464 山村游历(Wander)(LCT,Splay)

    洛谷题目传送门 LCT维护子树信息常见套路详见我的总结 闲话 题目摘自WC模拟试题(by Philipsweng),原题目名Wander,"山村游历"是自己搞出来的中文名. 数据自 ...

  5. 洛谷P3348 [ZJOI2016]大森林(LCT,虚点,树上差分)

    洛谷题目传送门 思路分析 最简单粗暴的想法,肯定是大力LCT,每个树都来一遍link之类的操作啦(T飞就不说了) 考虑如何优化算法.如果没有1操作,肯定每个树都长一样.有了1操作,就来仔细分析一下对不 ...

  6. 洛谷U19464 山村游历(Wander)(LCT)

    洛谷题目传送门 LCT维护子树信息常见套路详见我的总结 闲话 题目摘自WC模拟试题(by Philipsweng),原题目名Wander,"山村游历"是自己搞出来的中文名. 数据自 ...

  7. [洛谷P2597] [ZJOI2012]灾难

    洛谷题目链接:[ZJOI2012]灾难 题目描述 阿米巴是小强的好朋友. 阿米巴和小强在草原上捉蚂蚱.小强突然想,如果蚂蚱被他们捉灭绝了,那么吃蚂蚱的小鸟就会饿死,而捕食小鸟的猛禽也会跟着灭绝,从而引 ...

  8. 洛谷P4332 [SHOI2014]三叉神经树(LCT,树剖,二分查找,拓扑排序)

    洛谷题目传送门 你谷无题解于是来补一发 随便百度题解,发现了不少诸如树剖\(log^3\)LCT\(log^2\)的可怕描述...... 于是来想想怎么利用题目的性质,把复杂度降下来. 首先,每个点的 ...

  9. 洛谷P3613 睡觉困难综合征(LCT,贪心)

    洛谷题目传送门 膜拜神犇出题人管理员!!膜拜yler和ZSY!! 没错yler连续教我这个蒟蒻写起床困难综合症和睡觉困难综合症%%%Orz,所以按位贪心的思路可以继承下来 这里最好还是写树剖吧,不过我 ...

随机推荐

  1. 脱壳系列(五) - MEW 壳

    先用 PEiD 看一下 MEW 11 1.2 的壳 用 OD 载入程序 按 F8 进行跳转 往下拉 找到这个 retn 指令,并下断点 然后 F9 运行 停在该断点处后再按 F8 右键 -> 分 ...

  2. openLayers 3 之入门

    openLayers 3 之入门 openlayer是web GIS客户端开发提供的javascript类库,也是开源框架,可以加载本地数据进行展示地图 1.下载相关引用的js.css文件 2.类似于 ...

  3. Win7 资源管理器右键固定的文件夹不见了

    把常用的文件夹固定到任务栏的资源管理器右键菜单中 某天突然就不见了! %APPDATA%\Microsoft\Windows\Recent\AutomaticDestinations “最近" ...

  4. error C2039: 'SetDefaultDllDirectories'错误解决办法<转>

    使用VS2013+WDK8.1+Win7开发UMDF驱动,当使用了CComPtr类,包含了atlcomcli.h头文件却报错,错误如下: Error 3 error C2039: 'SetDefaul ...

  5. Bower 使用

    Bower:客户端库管理工具 来自<JavaScript 标准参考教程(alpha)>,by 阮一峰 目录 概述 常用操作 项目初始化 库的安装 库的搜索和查看 库的更新和卸载 列出所有库 ...

  6. @JsonIgnore

    @JsonIgnore 避免取JSON对象时无限递归的问题,过滤掉一些不需要的属性,说明createdDate这个属性不需要转成json,放到getter方法前生效

  7. 认识Echarts(网址:http://echarts.baidu.com/tutorial.html#ECharts%20%E7%89%B9%E6%80%A7%E4%BB%8B%E7%BB%8D)

    first.html: <!DOCTYPE html><html lang="en"><head> <meta charset=" ...

  8. js引用类型赋值,深拷贝与浅拷贝

    JS中引用类型使用等号“=” 赋值,相当于把原来对象的地址拷贝一份给新的对象,这样原来旧的对象与新的对象就指向同一个地址,改变其中一个对象就会影响另外那个对象,也就是所谓的浅拷贝.例如: var ar ...

  9. java算法 蓝桥杯 摆花

    问题描述 小明的花店新开张,为了吸引顾客,他想在花店的门口摆上一排花,共m盆.通过调查顾客的喜好,小明列出了顾客最喜欢的n种花,从1到n标号.为了在门口展出更多种花,规定第i种花不能超过ai盆,摆花时 ...

  10. 压力测试工具--Siege

    Siege是一款开源的压力测试工具,设计用于评估WEB应用在压力下的承受能力.可以根据配置对一个WEB站点进行多用户的并发访问,记录每个用户所有请求过程的相应时间,并在一定数量的并发访问下重复进行.s ...