[BZOJ]2594 水管局长数据加强版(Wc2006)
失踪人口回归。
LCT一直是小C的弱项,特别是这种维护链的信息的,写挂了就会调代码调到心态爆炸。
不过还好这一次的模板练习没有出现太多的意外。
Description
Input
Output
按顺序对应输入文件中每一项k=1的任务,你需要输出一个数字和一个回车/换行符。该数字表示:你寻找到的水管路径中所有管道全都完成准备工作所需要的时间(当然要求最短)。
Sample Input
4 4 3
1 2 2
2 3 3
3 4 2
1 4 2
1 1 4
2 1 4
1 1 4
Sample Output
2
3
HINT
N ≤ 100000
M ≤ 1000000
Q ≤ 100000
任何时候我们考虑的水管网络都是连通的,即从任一结点A必有至少一条水管路径通往任一结点B。
Solution
很容易看出题目要求我们维护无向图的最小生成树,查询两点树上路径最大权值,并支持删边操作。
删边不好处理,而且题目没有要求我们在线,我们很容易想到倒过来做,把删边改为加边。
于是用hash判断删去了哪些边(注意hash可能会撞),对删去所有边之后的图做最小生成树。
这样就是LCT维护最小生成树的裸题了。
对于每条新加入的边,查找两端点之间路径最大权值,如果小于那个权值,就删去那条边,并加入这条边。
#include <cstdio>
#include <cstring>
#include <algorithm>
#define l(a) son[a][0]
#define r(a) son[a][1]
#define nrt(a) (l(fa[a])==a || r(fa[a])==a)
#define MM 1000005
#define MN 100005
#define mod 10000007
using namespace std;
struct meg1{int x,y,z;}a[MM];
struct meg2{int g,x,y,z,pos;}b[MN];
struct edge{int nex,to,wt,pos;}e[MN<<];
struct dmp{dmp *nex; int x,y,val;}*mp[mod];
int son[MN][],fa[MN],tfa[MN],tson[MN],tg[MN],mx[MN];
int hr[MN],hua[MN],pin;
int n,m,p; inline int read()
{
int n=,f=; char c=getchar();
while (c<'' || c>'') {if(c=='-')f=-; c=getchar();}
while (c>='' && c<='') {n=n*+c-''; c=getchar();}
return n*f;
} void revs(int x) {tg[x]^=; swap(l(x),r(x)); swap(tfa[x],tson[x]);}
void down(int x) {if (tg[x]) {revs(l(x)); revs(r(x)); tg[x]=;}}
int L(int x) {down(x); return l(x)?L(l(x)):x;}
void aldown(int x) {if (nrt(x)) aldown(fa[x]); down(x);}
void upd(int &x,int y) {if (a[y].z>a[x].z) x=y;}
void update(int x) {mx[x]=; upd(mx[x],tfa[x]); upd(mx[x],tson[x]); upd(mx[x],mx[l(x)]); upd(mx[x],mx[r(x)]);}
void rotate(int x)
{
register int y,z,l,r;
y=fa[x]; z=fa[y]; l=r(y)==x; r=l^;
if (nrt(y)) son[z][r(z)==y]=x;
fa[y]=x; fa[x]=z; fa[son[x][r]]=y;
son[y][l]=son[x][r]; son[x][r]=y;
update(y);
}
void splay(int x)
{
aldown(x);
register int y,z;
for (;nrt(x);rotate(x))
{y=fa[x]; if (nrt(y)) z=fa[y],rotate(r(z)==y^r(y)==x?x:y);}
update(x);
}
void access(int x)
{
for (int i=;x;x=fa[i=x])
{
splay(x); tson[x]=tfa[L(i)];
r(x)=i; update(x);
}
} int getmx(int x,int y)
{
access(x); splay(x); revs(x);
access(y); splay(y); return mx[y];
}
void link(int x,int y,int z)
{
access(x); splay(x);
access(y); splay(y); revs(y);
fa[y]=x; r(x)=y; tfa[y]=tson[x]=z;
update(y); update(x);
}
void cut(int x,int y)
{
access(x); splay(x); revs(x);
access(y); splay(y);
l(y)=fa[l(y)]=; tson[x]=tfa[y]=;
update(x); update(y);
} inline void ins(int x,int y,int z,int w)
{
e[++pin]=(edge){hr[x],y,z,w}; hr[x]=pin;
e[++pin]=(edge){hr[y],x,z,w}; hr[y]=pin;
}
void dfs(int x,int fat)
{
fa[x]=fat;
for (register int i=hr[x];i;i=e[i].nex)
if (e[i].to!=fat) mx[e[i].to]=tfa[e[i].to]=e[i].pos,dfs(e[i].to,x);
}
inline bool gather(int x,int y)
{
if (x==y) return false;
hua[x]=y; return true;
}
int getf(int x) {return hua[x]?hua[x]=getf(hua[x]):x;}
bool cmp(const meg1& a,const meg1& b) {return a.z<b.z;} int seamp(int h,int x,int y)
{
for (dmp* q=mp[h];q;q=q->nex) if (q->x==x && q->y==y) return q->val;
return ;
}
void insmp(int h,int x,int y,int z)
{
dmp* q=new(dmp);
q->nex=mp[h]; q->x=x; q->y=y; q->val=z; mp[h]=q;
}
int geth(int x,int y) {return (1LL*x*+y)%mod;} int main()
{
register int i,lt;
n=read(); m=read(); p=read();
for (i=;i<=m;++i)
{
a[i].x=read(); a[i].y=read(); a[i].z=read();
if (a[i].x>a[i].y) swap(a[i].x,a[i].y);
}
for (i=;i<=p;++i)
{
b[i].g=read(); b[i].x=read(); b[i].y=read();
if (b[i].x>b[i].y) swap(b[i].x,b[i].y);
if (b[i].g==) insmp(geth(b[i].x,b[i].y),b[i].x,b[i].y,i);
}
sort(a+,a+m+,cmp);
for (i=;i<=m;++i)
{
if (lt=seamp(geth(a[i].x,a[i].y),a[i].x,a[i].y)) {b[lt].pos=i; continue;}
if (gather(getf(a[i].x),getf(a[i].y))) ins(a[i].x,a[i].y,a[i].z,i);
}
dfs(,);
for (i=p;i;--i)
{
if (b[i].g==) b[i].z=a[getmx(b[i].x,b[i].y)].z;
else if (b[i].g==) {if (a[b[i].pos].z<a[lt=getmx(b[i].x,b[i].y)].z) cut(a[lt].x,a[lt].y),link(b[i].x,b[i].y,b[i].pos);}
}
for (i=;i<=p;++i) if (b[i].g==) printf("%d\n",b[i].z);
}
Last Word
由于link和cut部分可能有点难以理解,LCT一直是令小C头疼的算法之一,但是小C还是成功把模板默出来了。
然后迷之RE,并且发现树上部分节点的关系违背了伦理道德。调完hash之后,结果发现是在找最左边的节点的节点时忘记down操作了。
果然LCT在维护信息时,考虑哪里需要update,哪里需要down,顺序是什么是最烦的。
不得不说,D-map真的好用。
[BZOJ]2594 水管局长数据加强版(Wc2006)的更多相关文章
- bzoj 2594: 水管局长数据加强版 Link-Cut-Tree
题目: Description SC省MY市有着庞大的地下水管网络,嘟嘟是MY市的水管局长(就是管水管的啦),嘟嘟作为水管局长的工作就是:每天供水公司可能要将一定量的水从x处送往y处,嘟嘟需要为供水公 ...
- BZOJ 2594 水管局长数据加强版(动态树)
题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2594 题意:给出一个无向图,边有权值.定义一条路径的长度为该路径所有边的最大值.两种操作 ...
- BZOJ 2594 水管局长数据加强版
LCT维护最小生成树 要求两点路径最大的最小,首先想到的肯定是最小生成树,再加上有删边操作,那就得用LCT维护了. 可是对于cut一条边,我们要时刻维护图中的最小生成树,需要把之前被我们淘汰的边找回, ...
- bzoj 2594: [Wc2006]水管局长数据加强版 动态树
2594: [Wc2006]水管局长数据加强版 Time Limit: 25 Sec Memory Limit: 128 MBSubmit: 934 Solved: 291[Submit][Sta ...
- BZOJ 2594: [Wc2006]水管局长数据加强版( LCT )
离线然后就是维护加边的动态MST, Link cut tree秒掉..不过我写+调了好久...时间复杂度O(NlogN + MlogM) ------------------------------- ...
- BZOJ 2594: [Wc2006]水管局长数据加强版 [LCT kruskal]
2594: [Wc2006]水管局长数据加强版 Time Limit: 25 Sec Memory Limit: 128 MBSubmit: 2917 Solved: 918[Submit][St ...
- BZOJ 2594 【WC2006】 水管局长数据加强版
题目链接:水管局长数据加强版 好久没写博客了…… 上次考试的时候写了一发LCT,但是写挂了……突然意识到我已经很久没有写过LCT了,于是今天找了道题来练练手. 首先,LCT这里不讲.这道题要求支持动态 ...
- BZOJ2594: [Wc2006]水管局长数据加强版
题解: 裸LCT+离线+二分+MST... 代码:(几乎摘抄自hzwer) #include<cstdio> #include<cstdlib> #include<cma ...
- [bzoj2594][Wc2006]水管局长数据加强版 (lct)
论蒟蒻的自我修养T_T.. 和noi2014魔法森林基本一样...然而数据范围大得sxbk...UPD:这题如果用lct判联通的话可能会被卡到O(mlogm)..所以最好还是用并查集吧 一开始数组开太 ...
随机推荐
- XCode Build Settings中几种Search Paths
Header search path:去查找头文件的路径,同在在你需要使用第三方库的时候,在这里设置你的头文件路径目录,如图 <code><span class="str& ...
- Faster R-CNN 的 RPN 是啥子?
 Faster R-CNN,由两个模块组成: 第一个模块是深度全卷积网络 RPN,用于 region proposal; 第二个模块是Fast R-CNN检测器,它使用了RPN产生的region p ...
- css精简命名
想写写前言啥的,发现自己是前言无能星人. 简单吐吐槽好了,来到新公司,接手公司之前的项目,我想着也就是改改bug,慢慢来吧,粗略看了看这个项目的代码,目前仅看了html和css样式的,忍不住吐血三升. ...
- 用anaconda安装最新的TensorFlow版本
Google发布了TensorFlow1.4正式版 在anaconad搜索依旧是1.2的版本,通过一番查阅,找到了方法 1,打开anaconda-prompt 2,激活你要安装的环境 activate ...
- ArrayList源码学习----JDK1.7
什么是ArrayList? ArrayList是存储一组数据的集合,底层也是基于数组的方式实现,实际上也是对数组元素的增删改查:它的主要特点是: 有序:(基于数组实现) 随机访问速度快:(进行随机访问 ...
- 新概念英语(1-129)Seventy miles an hour
Lesson 129 Seventy miles an hour 时速70英里 Listen to the tape then answer this question. What does Ann ...
- 前端之BOM和DOM
BOM和DOM简介 BOM(Browser Object Model)是指浏览器对象模型,它使JavaScript有能力与浏览器进行“对话”. DOM(Document Object Model)是指 ...
- Java面向对象之封装 入门实例(一)
一.基础概念 (一)面向对象的三大特征: 1.封装 2.继承 3.多态 (二)封装:隐藏实现细节,对外提供公共的访问方式(接口). 封装的体现之一:将属性都 ...
- git初试
在gitLab上新建一个项目,creat项目文件之后,进入到项目的路径之后,复制命令git clone ‘git@gitlab.touzila.com:xiacaixiang/gitgitTest1. ...
- python—-模块与包1
模块与包 1 什么是模块? 一个模块就是一个包含了python定义和声明的文件,文件名就是模块名字加上.py的后缀 2 为何要使用模块? 如果你对出python解释器然后重新进入,那么你之前定义的函数 ...