洛谷4172 WC2006水管局长(LCT维护最小生成树)
这个题和魔法森林感觉有很相近的地方啊
同样也是维护一个类似最大边权最小的生成树
但是不同的是,这个题是有\(cut\)和询问,两种操作....
这可如何是好啊?
我们不妨倒着来考虑,假设所有要\(cut\)的边全都不存在,倒序做这个问题,不就是相当于在支持\(link\)操作吗?
那么就和之前的问题大致上是一样的了
对于\(u->v\)
如果\(findroot(u)!=findroot(v)\),就直接连边。
如果\(findroot(u)==findroot(v)\),就判断原来两个点之间的路径的最大值是不是大于当前值,如果大于就替换
直接上代码
// luogu-judger-enable-o2
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
#include<cmath>
#include<map>
#include<set>
#define mk make_pair
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while (!isdigit(ch)) {if (ch=='-') f=-1;ch=getchar();}
while (isdigit(ch)) {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return x*f;
}
const int maxn = 4e5+1e2;
struct Node{
int opt;
int x,y;
};
int ch[maxn][3];
int siz[maxn];
int fa[maxn];
int mx[maxn],mxpos[maxn];
int n,m;
int rev[maxn];
map<pair<int,int>,int> mp;
int q;
int x[maxn],y[maxn],w[maxn];
int val[maxn];
Node ymh[maxn];
int son(int x)
{
if (ch[fa[x]][0]==x) return 0;
else return 1;
}
bool notroot(int x)
{
return ch[fa[x]][0]==x || ch[fa[x]][1]==x;
}
void update(int x)
{
mx[x]=val[x];
mxpos[x]=x;
if (ch[x][0])
{
if (mx[ch[x][0]]>mx[x])
{
mx[x]=mx[ch[x][0]];
mxpos[x]=mxpos[ch[x][0]];
}
}
if (ch[x][1])
{
if (mx[ch[x][1]]>mx[x])
{
mx[x]=mx[ch[x][1]];
mxpos[x]=mxpos[ch[x][1]];
}
}
}
void reverse(int x)
{
swap(ch[x][0],ch[x][1]);
rev[x]^=1;
}
void pushdown(int x)
{
if (rev[x])
{
if (ch[x][0]) reverse(ch[x][0]);
if (ch[x][1]) reverse(ch[x][1]);
rev[x]=0;
}
}
void rotate(int x)
{
int y=fa[x],z=fa[y];
int b=son(x),c=son(y);
if (notroot(y)) ch[z][c]=x;
fa[x]=z;
ch[y][b]=ch[x][!b];
fa[ch[x][!b]]=y;
ch[x][!b]=y;
fa[y]=x;
update(y);
update(x);
}
int st[maxn];
void splay(int x)
{
int y=x,cnt=0;
st[++cnt]=y;
while (notroot(y)) y=fa[y],st[++cnt]=y;
while (cnt) pushdown(st[cnt--]);
while (notroot(x))
{
int y=fa[x],z=fa[y];
int b=son(x),c=son(y);
if (notroot(y))
{
if (b==c) rotate(y);
else rotate(x);
}
rotate(x);
}
update(x);
}
void access(int x)
{
for (int y=0;x;y=x,x=fa[x])
{
splay(x);
ch[x][1]=y;
update(x);
}
}
void makeroot(int x)
{
access(x);
splay(x);
reverse(x);
}
int findroot(int x)
{
access(x);
splay(x);
while (ch[x][0])
{
pushdown(x);
x=ch[x][0];
}
return x;
}
void split(int x,int y)
{
makeroot(x);
access(y);
splay(y);
}
void link(int x,int y)
{
makeroot(x);
if (findroot(y)!=x) fa[x]=y;
}
void cut(int x,int y)
{
split(x,y);
if (ch[x][0] || ch[x][1] || fa[x]!=y || ch[y][son(x)^1]) return;
fa[x]=ch[y][0]=0;
}
int vis[maxn];
int ans[maxn];
int main()
{
n=read(),m=read(),q=read();
for (int i=1;i<=m;i++)
{
x[i]=read(),y[i]=read(),w[i]=read();
val[i+n]=w[i];
mp[mk(x[i],y[i])]=mp[mk(y[i],x[i])]=i;
}
for (int i=1;i<=q;i++)
{
ymh[i].opt=read();
ymh[i].x=read();
ymh[i].y=read();
if (ymh[i].opt==2) vis[mp[mk(ymh[i].x,ymh[i].y)]]=1;
}
for (int i=1;i<=m;i++)
{
if (vis[i]) continue;
if (findroot(x[i])!=findroot(y[i]))
{
link(x[i],i+n);
link(y[i],i+n);
mp[mk(x[i],y[i])]=mp[mk(y[i],x[i])]=i+n;
}
else
{
split(x[i],y[i]);
int now =mxpos[y[i]];
if (mx[y[i]]<w[i]) continue;
cut(x[now-n],now);
cut(y[now-n],now);
mp[mk(x[now-n],y[now-n])]=mp[mk(y[now-n],x[now-n])]=0;
link(x[i],i+n);
link(y[i],i+n);
mp[mk(x[i],y[i])]=mp[mk(y[i],x[i])]=i+n;
}
}
int tmp=0;
for (int j=q;j>=1;j--)
{
if (ymh[j].opt==1)
{
split(ymh[j].x,ymh[j].y);
ans[++tmp]=mx[ymh[j].y];
//printf("%d\n",mx[ymh[j].y]);
}
else
{
int i=mp[mk(ymh[j].x,ymh[j].y)];
if (findroot(x[i])!=findroot(y[i]))
{
link(x[i],i+n);
link(y[i],i+n);
//mp[mk(x[i],y[i])]=mp[mk(y[i],x[i])]=i+n;
}
else
{
split(x[i],y[i]);
int now =mxpos[y[i]];
if (mx[y[i]]<val[i+n]) continue;
cut(x[now-n],now);
cut(y[now-n],now);
//mp[mk(x[now-n],y[now-n])]=mp[mk(y[now-n],x[now-n])]=0;
link(x[i],i+n);
link(y[i],i+n);
//mp[mk(x[i],y[i])]=mp[mk(y[i],x[i])]=i+n;
}
}
}
for (int i=tmp;i>=1;i--)
{
printf("%d\n",ans[i]);
}
return 0;
}
洛谷4172 WC2006水管局长(LCT维护最小生成树)的更多相关文章
- 洛谷.4172.[WC2006]水管局长(LCT Kruskal)
题目链接 洛谷(COGS上也有) 不想去做加强版了..(其实处理一下矩阵就好了) 题意: 有一张图,求一条x->y的路径,使得路径上最长边尽量短并输出它的长度.会有<=5000次删边. 这 ...
- 洛谷 4172 [WC2006]水管局长
[题解] 我们把操作倒过来做,就变成了加边而不是删边.于是用LCT维护动态加边的最小生成树就好了.同样要注意把边权变为点权. #include<cstdio> #include<al ...
- P4172 [WC2006]水管局长 LCT维护最小生成树
\(\color{#0066ff}{ 题目描述 }\) SC 省 MY 市有着庞大的地下水管网络,嘟嘟是 MY 市的水管局长(就是管水管的啦),嘟嘟作为水管局长的工作就是:每天供水公司可能要将一定量的 ...
- [洛谷P4172] WC2006 水管局长
问题描述 SC省MY市有着庞大的地下水管网络,嘟嘟是MY市的水管局长(就是管水管的啦),嘟嘟作为水管局长的工作就是:每天供水公司可能要将一定量的水从x处送往y处,嘟嘟需要为供水公司找到一条从A至B的水 ...
- 洛谷P4172 [WC2006]水管局长 (LCT,最小生成树)
洛谷题目传送门 思路分析 在一个图中,要求路径上最大边边权最小,就不难想到最小生成树.而题目中有删边的操作,那肯定是要动态维护啦.直接上LCT维护边权最小值(可以参考一下蒟蒻的Blog) 这时候令人头 ...
- 洛谷P4172 [WC2006]水管局长(lct求动态最小生成树)
SC省MY市有着庞大的地下水管网络,嘟嘟是MY市的水管局长(就是管水管的啦),嘟嘟作为水管局长的工作就是:每天供水公司可能要将一定量的水从x处送往y处,嘟嘟需要为供水公司找到一条从A至B的水管的路径, ...
- luogu P4172 [WC2006]水管局长 LCT维护动态MST + 离线
Code: #include<bits/stdc++.h> #define maxn 1200000 #define N 120000 using namespace std; char ...
- 【洛谷P4172】水管局长
题目大意:给定 N 个点,M 条边的无向图,支持两种操作:动态删边和查询任意两点之间路径上边权的最大值最小是多少. 题解: 引理:对原图求最小生成树,可以保证任意两点之间的路径上边权的最大值取得最小值 ...
- P4172 [WC2006]水管局长(LCT)
P4172 [WC2006]水管局长 LCT维护最小生成树,边权化点权.类似 P2387 [NOI2014]魔法森林(LCT) 离线存储询问,倒序处理,删边改加边. #include<iostr ...
随机推荐
- Kubernetes集群部署笔记
本作品由Galen Suen采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可.由原作者转载自个人站点. 概述 本文用于整理基于Debian操作系统使用kubeadm工具部署Kub ...
- rEFI引导Win10+Ubuntu14双系统
公司买了一台Alienware 15 R2,安装双系统折腾死我了,现在记录一下安装过程. 硬盘: 256固态+1T机械 安装顺序: 先Windows,再Ubuntu 不同BIOS启动方式下安装系统 U ...
- jmeter实际场景应用之测试上传excel文件
日常工作上测试的时候,会有一些场景是导入/上传文件.我们系统多是excel文件,这里就用excel文件为例,详述一下此次测试遇到的坑.最终结果是成功的,请看到最后! 1.获取接口的一些参数信息 先按F ...
- eslint and stylelint config
eslint: module.exports = { root: true, env: { browser: true, es6: true, node: true ...
- sublime text 3 中文排序插件
ST3 的排序不支持中文按拼音排序,所以需要搞一个插件来支持这一特性 pypinyin 这个库可以把中文转成拼音,可惜不支持 python3.3,而 ST3 内置的 python 就是 3.3 我系统 ...
- Kubernetes-kubectl介绍
前言 本篇是Kubernetes第三篇,大家一定要把环境搭建起来,看是解决不了问题的,必须实战.本篇重要介绍kubectl的使用. Kubernetes系列文章: Kubernetes介绍 Kuber ...
- Docker | 入门 & 基础操作
Dcoker 入门 确保docker 已经安装好了,如没有装好的可以参考:Docker | 安装 运行第一个容器 docker run -it ubuntu /bin/bash docker run ...
- ☕【Java技术指南】「并发编程专题」Fork/Join框架基本使用和原理探究(基础篇)
前提概述 Java 7开始引入了一种新的Fork/Join线程池,它可以执行一种特殊的任务:把一个大任务拆成多个小任务并行执行. 我们举个例子:如果要计算一个超大数组的和,最简单的做法是用一个循环在一 ...
- C#开源类库SimpleTCP
目录 简介 使用方法 实现客户端 实现服务端 总结 简介 工作中经常遇到需要实现TCP客户端或服务端的时候,如果每次都自己写会很麻烦且无聊,使用SuperSocket库又太大了.这时候就可以使用Sim ...
- 八、Abp vNext 基础篇丨标签聚合功能
介绍 本章节先来把上一章漏掉的上传文件处理下,然后实现Tag功能. 上传文件 上传文件其实不含在任何一个聚合中,它属于一个独立的辅助性功能,先把抽象接口定义一下,在Bcvp.Blog.Core.App ...