【Luogu】P4172水管局长(LCT)
有个结论是x到y的路径上最长边权值等于最小生成树上最长边权值,于是问题转化为最小生成树。
再考虑把问题反过来,删边变成加边。
于是变成动态维护最小生成树,LCT可以做到。
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cctype>
#include<cstring>
#include<map>
#define maxn 200020
using namespace std;
inline long long read(){
long long num=,f=;
char ch=getchar();
while(!isdigit(ch)){
if(ch=='-') f=-;
ch=getchar();
}
while(isdigit(ch)){
num=num*+ch-'';
ch=getchar();
}
return num*f;
} struct Edge{
int from,to,val;
bool operator <(const Edge &a)const{ return val<a.val; }
}edge[maxn]; int stack[maxn],top; struct Splay{
struct Node{
int e[],fa,mini,tag,val,maxi;
}tree[maxn];
inline int iden(int x){ return x==tree[tree[x].fa].e[]; }
inline void connect(int x,int fa,int how){ tree[x].fa=fa; tree[fa].e[how]=x; }
inline bool isroot(int x){ return tree[tree[x].fa].e[]!=x&&tree[tree[x].fa].e[]!=x; }
inline void update(int x){
int le=tree[x].e[],ri=tree[x].e[]; tree[x].maxi=tree[x].val;
if(edge[tree[le].maxi].val>edge[tree[x].maxi].val) tree[x].maxi=tree[le].maxi;
if(edge[tree[ri].maxi].val>edge[tree[x].maxi].val) tree[x].maxi=tree[ri].maxi;
}
inline void reverse(int x){
swap(tree[x].e[],tree[x].e[]);
tree[x].tag^=;
}
inline void pushdown(int x){
if(tree[x].tag==) return;
if(tree[x].e[]) reverse(tree[x].e[]);
if(tree[x].e[]) reverse(tree[x].e[]);
tree[x].tag=;
}
void rotate(int x){
int y=tree[x].fa,r=tree[y].fa;
int sony=iden(x),sonr=iden(y);
tree[x].fa=r; if(!isroot(y)) tree[r].e[sonr]=x;
int b=tree[x].e[sony^];
connect(b,y,sony);
connect(y,x,sony^);
update(y);
}
inline void pushto(int x){
top=;
while(!isroot(x)){
stack[++top]=x;
x=tree[x].fa;
}
pushdown(x);
while(top) pushdown(stack[top--]);
}
void splay(int x){
pushto(x);
while(!isroot(x)){
int fa=tree[x].fa;
if(!isroot(fa))
if(iden(fa)==iden(x)) rotate(fa);
else rotate(x);
rotate(x);
}
update(x);
}
inline void access(int x){
int last=;
while(x){
splay(x);
tree[x].e[]=last;
update(x);
last=x; x=tree[x].fa;
}
}
inline void makeroot(int x){
access(x);
splay(x);
reverse(x);
}
inline int findroot(int x){
access(x);
splay(x);
while(tree[x].e[]) x=tree[x].e[];
return x;
}
inline void split(int x,int y){
makeroot(x);
access(y);
splay(y);
}
inline void link(int x,int y){
//printf("%d %d\n",x,y);
split(x,y);
tree[x].fa=y;
}
inline void cut(int x,int y){
//printf("%d %d\n",x,y);
split(x,y);
if(tree[y].e[]!=x||tree[x].e[]) return;
tree[x].fa=tree[y].e[]=;
}
}s; struct Que{
int opt,x,y,id,cnt;
}q[maxn];
int cnt; int ans[maxn]; int d[maxn*]; bool vis[maxn]; int main(){
int n=read(),m=read(),e=read();
for(int i=;i<=m;++i){
edge[i]=(Edge){read(),read(),read()};
if(edge[i].from>edge[i].to) swap(edge[i].from,edge[i].to);
}
sort(edge+,edge+m+);
for(int i=;i<=m;++i){
//printf("%d %d>><\n",edge[i].from,edge[i].to);
s.tree[i+n].mini=s.tree[i+n].val=i;
d[edge[i].from*n+edge[i].to]=i;
}
for(int i=;i<=e;++i){
q[i]=(Que){read(),read(),read(),};
if(q[i].x>q[i].y) swap(q[i].x,q[i].y);
if(q[i].opt==) q[i].id=++cnt;
else{
int now=d[q[i].x*n+q[i].y];
q[i].cnt=now;
//printf("%d\n",now);
vis[now]=;
}
}
int sum=;
for(int i=;i<=m;++i){
if(sum==n-) break;
if(vis[i]) continue;
if(s.findroot(edge[i].from)==s.findroot(edge[i].to)) continue;
s.link(edge[i].from,i+n);
s.link(edge[i].to,i+n);
sum++;
}
for(int i=e;i;--i){
if(q[i].opt==){
s.split(q[i].x,q[i].y);
ans[q[i].id]=edge[s.tree[q[i].y].maxi].val;
}
else{
s.split(q[i].x,q[i].y);
int now=q[i].cnt;
int ret=s.tree[q[i].y].maxi;
if(edge[now].val<edge[ret].val){
if(edge[ret].from) s.cut(edge[ret].from,ret+n);
if(edge[ret].to) s.cut(edge[ret].to,ret+n);
s.link(q[i].x,now+n);
s.link(q[i].y,now+n);
}
}
}
for(int i=;i<=cnt;++i) printf("%d\n",ans[i]);
return ;
}
【Luogu】P4172水管局长(LCT)的更多相关文章
- luogu P4172 [WC2006]水管局长 LCT维护动态MST + 离线
Code: #include<bits/stdc++.h> #define maxn 1200000 #define N 120000 using namespace std; char ...
- P4172 [WC2006]水管局长 LCT维护最小生成树
\(\color{#0066ff}{ 题目描述 }\) SC 省 MY 市有着庞大的地下水管网络,嘟嘟是 MY 市的水管局长(就是管水管的啦),嘟嘟作为水管局长的工作就是:每天供水公司可能要将一定量的 ...
- 洛谷.4172.[WC2006]水管局长(LCT Kruskal)
题目链接 洛谷(COGS上也有) 不想去做加强版了..(其实处理一下矩阵就好了) 题意: 有一张图,求一条x->y的路径,使得路径上最长边尽量短并输出它的长度.会有<=5000次删边. 这 ...
- BZOJ 2594 水管局长 - LCT 维护链信息
Solution 由于链信息不好直接维护, 所以新建一个节点存储边的权值, 并把这个节点连向 它所连的节点 $u$, $v$ $pushup$中更新维护的 $mx$ 指向路径上权值最大的边的编号. 由 ...
- 洛谷4172 WC2006水管局长(LCT维护最小生成树)
这个题和魔法森林感觉有很相近的地方啊 同样也是维护一个类似最大边权最小的生成树 但是不同的是,这个题是有\(cut\)和询问,两种操作.... 这可如何是好啊? 我们不妨倒着来考虑,假设所有要\(cu ...
- P4172 [WC2006]水管局长(LCT)
P4172 [WC2006]水管局长 LCT维护最小生成树,边权化点权.类似 P2387 [NOI2014]魔法森林(LCT) 离线存储询问,倒序处理,删边改加边. #include<iostr ...
- 洛谷P4172 [WC2006]水管局长(lct求动态最小生成树)
SC省MY市有着庞大的地下水管网络,嘟嘟是MY市的水管局长(就是管水管的啦),嘟嘟作为水管局长的工作就是:每天供水公司可能要将一定量的水从x处送往y处,嘟嘟需要为供水公司找到一条从A至B的水管的路径, ...
- P4172 [WC2006]水管局长
P4172 [WC2006]水管局长 前言 luogu数据太小 去bzoj,他的数据大一些 思路 正着删不好维护 那就倒着加,没了 LCT维护他的最小生成树MST 树上加一条边肯定会有一个环 看看环上 ...
- BZOJ 2594: [Wc2006]水管局长数据加强版(kruskal + LCT)
Description SC省MY市有着庞大的地下水管网络,嘟嘟是MY市的水管局长(就是管水管的啦),嘟嘟作为水管局长的工作就是:每天供水公司可能要将一定量的水从x处送往y处,嘟嘟需要为供水公司找到一 ...
随机推荐
- 深入理解计算机系统_3e 第十章家庭作业 CS:APP3e chapter 10 homework
10.6 1.若成功打开"foo.txt": -->1.1若成功打开"baz.txt": 输出"4\n" -->1.2若未能成功 ...
- Python判断一个数是否为小数
一.判断一个数是否为小数 1.有且仅有一个小数点 2.小数点的左边可能为正数或负数 3.小数点的右边为正数 二.实现代码 def is_float(str): if str.count('.') == ...
- vs2015“当前不会命中断点 还没有为该文档加载任何符号”的解决方法
解决方法:工具-选项-调试 -(启用“仅我的代码”)勾去掉
- CUDA中记录执行时间-GPU端
事件eventcudaEvent_t start,stop;cudaEventCreate(&start);cudaEventCreate(&stop);cudaEventRecord ...
- Linux学习记录(一)
1.Linux的简介 1.1.Linux的概述 Linux是基于Unix的开源免费的操作系统,由于系统的稳定性和安全性几乎成为程序代码运行的最佳系统环境.Linux是由Linus Torvalds(林 ...
- C#逻辑运算符
一.C#逻辑运算符 C#语言的逻辑运算符是对变量的值.表达式的运算结果进行比较,基比较结果为True或False. 二.示例 using System;using System.Collections ...
- Angular2 Service获取json数据
在Angular2框架下一般交互解析json是要用到Service的,其实除了Service还是很多的,今天先写个最简单的前后端数据交互 嗯~~ 首先我先在app包下直接创建Service 好了 这里 ...
- linux 下备份mysql数据库
今天老板让备份数据库没办法自己折腾吧,下面把折腾的结果总结总结. 数据库备份思路: 1.编写脚本 2.执行脚本 哈哈,是不是很简单,打开冰箱,放入大象,关上.下面我是具体操作. 一.编写脚本 1.设 ...
- 【jenkins】【java】【tomcat】windows host key verification failed
适用于windows系统 出现这个问题的原因tomcat启动的用户找不到本地公私钥路径 如果tomcat 启动时候选择 local system account (默认此选项),请把你的公私钥文件(i ...
- Linux常见的系統进程
前言 在日常运维工作中,经常会看到一些奇怪的系统进程占用资源比较高.而且总是会听到业务线同学询问“xxx这个是啥进程啊?咋开启了这么多?” 而这些系统级的内核进程都是会用中括号括起来的,它们会执行一些 ...