【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处,嘟嘟需要为供水公司找到一 ...
随机推荐
- C语言中的异常处理机制
#define try if(!setjmp(Jump_Buffer)) 返回try现场后重新执行判断,所以有两次执行. http://blog.csdn.net/tian_dao_chou_qin/ ...
- 浅谈KD-Tree
前言 \(KD-Tree\)是一个十分神奇的东西,其实本质上类似于一个\(K\)维的二叉搜索树. 核心思想 \(KD-Tree\)的核心思想与\(BST\)是差不多的(插入等操作也都基本上一样). 唯 ...
- 2017.12.20 Java中的 IO/XML学习总结 File类详细
IO / XML 一.File类 1.定义/概念 Java是面向对象的语言,要想把数据存到文件中,就必须要有一个对象表示这个文件.File类的作用就是代表一个特定的文件或目录,并提供了若干方法对这些文 ...
- bootstrap table加载数据
//html <table id="dailyDevTable"></table> //js $(function () { initTable(); }) ...
- vue切换路由时动画
安装个包 npm i nprogress 直接导入使用 最终的效果就是
- phpspider案例
phpspider案例 <?php require './autoload.php'; use phpspider\core\phpspider; /* Do NOT delete this c ...
- .net core 在IIS上发布502问题
本来迁移一个项目到.net core就是一件体力活,要找各种替代包,还有一些函数/属性的不支持 总之很头疼... 不要问我为什么用了.net core还要Host在IIS上,国内用.net的公司普遍都 ...
- vue.js 二 路由懒加载
当项目小的时候,我没考虑要去找这个得解决方案,也幸好现在几乎能迁移的项目都整合在了一个vue的项目里面 才发现编译后的vendor.js变得异常的大,而且几乎在项目每一个页面都需要加载这一个js,项目 ...
- python爬虫的基本思路
爬虫:请求网站并提取数据的自动化程序. 流程: 发送请求 -> 获取数据 -> 解析数据 -> 存储数据
- 单片机入门学习笔记5:STC下载器
STC下载器主要集成了, 1.芯片识别,下载/编程 2.端口识别 3.串口助手 4.KEIL仿真设置 5.芯片选型 6.范例程序 (集成了定时器,串口等例程) 7.波特率计算器 8.定时器计算器 9. ...