洛谷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 ...
随机推荐
- Panel添加边框颜色和边框粗细调整
Panel控件添加边框颜色 C# WinForm窗体控件Panel修改边框颜色以及边框宽度方法 - JiYF - 博客园 (cnblogs.com) 1.新建一个用户控件的项目,如下: 2.添加一个P ...
- C# 给PPT中的图表添加趋势线
本文内容分享通过C#程序代码给PPT文档中的图表添加数据趋势线的方法. 支持趋势线的图表类型包括二维面积图.条形图.柱形图.柱形图.股价图.xy (散点图) 和气泡图中:不能向三维.堆积.雷达图.饼图 ...
- adb 常用命令大全(1)- 汇总
adb 常用命令大全系列 基础命令 查看手机设备信息 应用管理 日志相关 模拟按键输入 其他实用功能
- 经典多级时间轮定时器(C语言版)
经典多级时间轮定时器(C语言版) 文章目录 经典多级时间轮定时器(C语言版) 1. 序言 2. 多级时间轮实现框架 2.1 多级时间轮对象 2.2 时间轮对象 2.3 定时任务对象 2.4 双向链表 ...
- java基础语法以及进制的转换
关键字 关键字: 被Java语言赋予特定含义的单词 关键字特点 组成关键字的字母全部小写 关键字注意事项 goto和const作为保留字存在,目前并不使用 类似IDEA这样的集成工具,针对关键字有特殊 ...
- 【第十七篇】- Maven Web 应用之Spring Cloud直播商城 b2b2c电子商务技术总结
Maven Web 应用 本章节我们将学习如何使用版本控制系统 Maven 来管理一个基于 web 的项目,如何创建.构建.部署已经运行一个 web 应用. 创建 Web 应用 我们可以使用 mave ...
- 用python的pandas读取excel文件中的数据
一.读取Excel文件 使用pandas的read_excel()方法,可通过文件路径直接读取.注意到,在一个excel文件中有多个sheet,因此,对excel文件的读取实际上是读取指定文件.并 ...
- angularjs 文件上传
github连接地址:https://github.com/danialfarid/ng-file-upload 核心代码: html: <div class="form-group& ...
- 使用python实现xls批量转为xlsx
利用win32库来实现 # -*- coding:utf-8 -*- import os import win32com.client as win32 #需要转换的数据目录 inputdir = u ...
- 【OI】C++STL初步 排序与检索
从紫皮书过来的,但是书中内容讲的比较简洁,做一点补充笔记. 一.排序(sort函数) 头文件:<algorithm> 语法:sort(start,end,cmp); start,end必须 ...