洛谷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 ...
随机推荐
- Vue.JS快速上手(组件生命周期)
一.什么是组件 组成网页独立功能基本单元(片段), 复用.维护.性能, Vue.js中的组件就是一个Vue的实例,Vue中的组件包含data/methods/computed. 一个Vue.js的应用 ...
- 备忘:Linux内核编程的几个注意事项
虚拟地址转物理地址要用__pa 内核程序创建的一段地址连续的共享内存,通过内存映射可以让用户态进程存取.之前在RHEL/CentOS的x86_64架构上工作正常.后来在aarch64架构的银河麒麟(L ...
- 问题:idea 中文无法使用
1. 问题--idea无法使用中文输入 原因:idea本身版本过高,所以需要你强制减低它的jdk版本 解决:使用配置idea环境变量解决 ps:目前适用于任何版本的jdk和idea 步骤: 1.新建 ...
- kratos
技术文章 日志库的使用姿势 通过 layout 探索 kratos 运行原理 发版日志 发布日志 - kratos v2.0.5 版本发布 发布日志 - kratos v2.0.4 版本发布
- shell运算方式
1.(())--整数运算 [root@m01 /server/scripts]# a=1 [root@m01 /server/scripts]# b=2 [root@m01 /server/scrip ...
- noip模拟21
开题发现这场考过,定睛一看,发现是省选前最后一场,没改过呀--但是还是讲武德的赛时没提交 A. Median 神奇之处在于 \(1e7\) 个质数居然能线性筛出来~ 那么 \(S2\) 可以直接筛出来 ...
- Python常见问题 - python3 requests库提示警告InsecureRequestWarning的问题
当使用 requests 库发送请求时报了以下警告 D:\python3.6\lib\site-packages\urllib3\connectionpool.py:847: InsecureRequ ...
- IKEv1协商安全联盟的过程
IKEv1协商安全联盟的过程 采用IKEv1协商安全联盟主要分为两个阶段: 第一阶段,通信双方协商和建立IKE协议本身使用的安全通道,即建立一个IKE SA: 第二阶段,利用第一阶段已通过认证和安全保 ...
- vivo营销自动化技术解密|开篇
一.营销自动化概览 1.1. 什么是营销自动化 营销自动化是指专门为营销部门或组织设计的软件平台和技术,可以更有效地在线进行多渠道营销并使重复性任务自动化.营销部门和销售人员通过制定任务和流程的操作标 ...
- CodeForce-810B Summer sell-off (结构体排序)
http://codeforces.com/problemset/problem/810/B 已知n天里,已知第i天的供货量和需求量,给定一个f,可以在n天之中选f天促销使得供货量翻倍. 问选择其中f ...