BZOJ2594 水管局长数据加强版LCT
题意:
您有一个无向带权图,您需要支持两种操作。
- 询问两个点之间的最大权最小路径。
- 删除一条边。
分析:
众所周知,任意两点间最大权最小路径存在于最小生成树上,所以这道题可以动态维护最小生成树。
用到的数据结构是可以支持连边和断边的Link- Cut- Tree。
用LCT维护一棵最小生成树,是不可能支持在原图上删边这一操作的,因为既不知道删除的边是否在最小生成树上,也不了解(如果删除的是最小生成树上的边)删除之后该用哪条边来保证树的连通。
正难则反!
我们把操作和询问都读进来,倒着处理,然后删边变成连边操作。(读进来的时候把需要被删除的边都打上标记)要在处理之前把没有标记的边都连好。
维护最小生成树的方法是:在加一条边时,询问连通的两个点之间权值最大的边,之后与新边相比较,如果新边更优,那么将最劣的边删掉,连接新边,否则忽略新边。
LCT维护的是链上的点权,我们要维护边权,方法是把一条边转化成“边——点——边” 的形式,直接给点权即可,普通的点权值为零!
代码:
1 #include<bits/stdc++.h> 2 #define max(a,b,c) max(max(a,b),c) 3 #define lc(x) t[x][0] 4 #define rc(x) t[x][1] 5 using namespace std; 6 const int N=1500005; 7 struct node{int x,y,z,id;bool d;}e[N]; 8 struct query{int f,x,y,ans,id;}q[N]; 9 int t[N][2],rev[N],val[N],mx[N],fu[N]; 10 int s[N],tp=0,n,m,k,fa[N]; 11 char readchar(){ 12 static char buf[100000],*l=buf,*r=buf; 13 if(l==r) r=(l=buf)+fread(buf,1,100000,stdin); 14 if(l==r) return EOF;return *l++;} 15 int read(){ 16 int x=0,f=1;char ch=readchar(); 17 while(ch<'0'||ch>'9'){if(ch=='-') f=-f;ch=readchar();} 18 while(ch<='9'&&ch>='0'){x=(x<<3)+(x<<1)+ch-'0';ch=readchar();}; 19 return x*f; 20 } char pbuf[100000],*pp=pbuf; 21 void push(const char c) { 22 if(pp-pbuf==100000) fwrite(pbuf,1,100000,stdout),pp=pbuf; 23 *pp++=c; 24 } void write(int x) { 25 static int sta[35]; 26 int top=0; 27 do{sta[top++]=x%10,x/=10;}while(x); 28 while(top) push(sta[--top]+'0');push('\n'); 29 } bool operator< (node a,node b){ 30 return a.x==b.x?a.y<b.y:a.x<b.x; 31 } bool cmp(node a,node b){ 32 return a.z<b.z; 33 } bool cmp2(node a,node b){ 34 return a.id<b.id; 35 } int get(int x){ 36 return fa[x]==x?x:fa[x]=get(fa[x]); 37 } int find(int x,int y){ 38 int l=1,r=m;node p=(node){x,y,0,0,0}; 39 while(l<=r){ 40 int mid=l+r>>1; 41 if(e[mid]<p) l=mid+1; 42 else if(e[mid].x==x&&e[mid].y==y) return mid; 43 else r=mid-1; 44 } return 0; 45 } void pushup(int x){ 46 int ls=lc(x),rs=rc(x); 47 mx[x]=x; 48 if(val[mx[ls]]>val[mx[x]]) 49 mx[x]=mx[ls]; 50 if(val[mx[rs]]>val[mx[x]]) 51 mx[x]=mx[rs]; 52 } void pushdown(int x){ 53 int ls=lc(x),rs=rc(x); 54 if(rev[x]) rev[ls]^=1,rev[rs]^=1, 55 swap(lc(x),rc(x)),rev[x]=0;return; 56 } bool pdrt(int x){ 57 return lc(fu[x])!=x&&rc(fu[x])!=x; 58 } void rotate(int x){ 59 int y=fu[x];int z=fu[y]; 60 int dy=(rc(y)==x),dz=(rc(z)==y); 61 if(!pdrt(y)) t[z][dz]=x; 62 t[y][dy]=t[x][dy^1],fu[t[x][dy^1]]=y; 63 t[x][dy^1]=y;fu[y]=x;fu[x]=z; 64 pushup(y); 65 } void splay(int x){ 66 s[++tp]=x; 67 for(int i=x;!pdrt(i);i=fu[i]) 68 s[++tp]=fu[i];while(tp) 69 pushdown(s[tp--]); 70 while(!pdrt(x)){ 71 int y=fu[x];int z=fu[y];if(!pdrt(y)) 72 if(rc(y)==x^rc(z)==y) rotate(x); 73 else rotate(y);rotate(x); 74 } pushup(x); 75 } void access(int x){ 76 for(int i=0;x;x=fu[x]) 77 splay(x),rc(x)=i,i=x; 78 } void mkrt(int x){ 79 access(x),splay(x);rev[x]^=1; 80 } int fdrt(int x){ 81 access(x);splay(x); 82 while(lc(x)) pushdown(x),x=lc(x); 83 return x; 84 } void split(int x,int y){ 85 mkrt(x);access(y);splay(y); 86 } void link(int x,int y){ 87 mkrt(x);if(fdrt(y)!=x) fu[x]=y; 88 } void cut(int x,int y){ 89 mkrt(x); 90 if(fdrt(y)==x&&fu[x]==y&&!rc(x)) 91 fu[x]=t[y][0]=0;pushup(y); 92 } int ask(int x,int y){ 93 split(x,y);return mx[y]; 94 } signed main(){ 95 n=read();m=read();k=read(); 96 for(int i=1;i<=n;fa[i]=i,i++); 97 for(int i=1;i<=m;i++){ 98 e[i].x=read();e[i].y=read();e[i].z=read(); 99 if(e[i].x>e[i].y) swap(e[i].x,e[i].y); 100 } sort(e+1,e+1+m,cmp); 101 for(int i=1;i<=m;i++) 102 e[i].id=i,val[n+i]=e[i].z,mx[n+i]=n+i; 103 sort(e+1,e+1+m); 104 for(int i=1;i<=k;i++){ 105 q[i].f=read();q[i].x=read();q[i].y=read(); 106 if(q[i].f==2){ 107 if(q[i].x>q[i].y) swap(q[i].x,q[i].y); 108 int p=find(q[i].x,q[i].y); 109 e[p].d=1,q[i].id=e[p].id; 110 } 111 } sort(e+1,e+m+1,cmp2);int tot=0; 112 for(int i=1;i<=m;i++) 113 if(!e[i].d){ 114 int u=e[i].x,v=e[i].y; 115 int x=get(u),y=get(v); 116 if(x!=y){ 117 fa[x]=y;link(u,i+n);link(v,i+n); 118 tot++;if(tot==n-1) break; 119 } 120 } for(int i=k;i;i--) 121 if(q[i].f==1) 122 q[i].ans=val[ask(q[i].x,q[i].y)]; 123 else{ 124 int x=q[i].x,y=q[i].y,o=q[i].id; 125 int p=ask(x,y); 126 if(e[o].z<val[p]) 127 cut(e[p-n].x,p),cut(e[p-n].y,p), 128 link(x,o+n),link(y,o+n); 129 } for(int i=1;i<=k;i++) 130 if(q[i].f==1) write(q[i].ans); 131 fwrite(pbuf,1,pp-pbuf,stdout); 132 return 0; 133 }
Link-Cut-Tree
转载于:https://www.cnblogs.com/Alan-Luo/articles/10155902.html
BZOJ2594 水管局长数据加强版LCT相关推荐
- BZOJ_2594_[Wc2006]水管局长数据加强版_LCT
BZOJ_2594_[Wc2006]水管局长数据加强版_LCT Description SC省MY市有着庞大的地下水管网络,嘟嘟是MY市的水管局长(就是管水管的啦),嘟嘟作为水管局长的工作就是:每天供 ...
- 水管局长数据加强版:lct,时光倒流,最小生成树,边化点
Description: SC省MY市有着庞大的地下水管网络,嘟嘟是MY市的水管局长(就是管水管的啦),嘟嘟作为水管局长的工作就是:每天供水公司可能要将一定量的水从x处送往y处,嘟嘟需要为供水公司找到 ...
- [BZOJ 2594] [Wc2006]水管局长数据加强版 【LCT】
题目链接:BZOJ - 2594 题目分析 这道题如果没有删边的操作,那么就是 NOIP2013 货车运输,求两点之间的一条路径,使得边权最大的边的边权尽量小. 那么,这条路径就是最小生成树上这两点之 ...
- 沉迷Link-Cut tree无法自拔之:[BZOJ2594][Wc2006]水管局长数据加强版
来自蒟蒻 \(Hero \_of \_Someone\) 的 \(LCT\) 学习笔记 $ $ 这应该算是道套路题吧, 如果将图中的边转换成点, 再将边权变点权, 就可以用 \(LCT\) 来维护了 ...
- 2017.10.16 水管局长水管局长数据加强版 思考记录
在ISA的指点下,彻底理解了lct(以前可能学了假的lct) 这个题不难想,就是倒着加边然后维护链上信息.. 但这题常数巨卡,卡map卡开局不上kruskal卡多余splay卡少用splay. 一般这 ...
- P4172 [WC2006]水管局长 LCT维护最小生成树
\(\color{#0066ff}{ 题目描述 }\) SC 省 MY 市有着庞大的地下水管网络,嘟嘟是 MY 市的水管局长(就是管水管的啦),嘟嘟作为水管局长的工作就是:每天供水公司可能要将一定量的 ...
- [洛谷P4172] WC2006 水管局长
问题描述 SC省MY市有着庞大的地下水管网络,嘟嘟是MY市的水管局长(就是管水管的啦),嘟嘟作为水管局长的工作就是:每天供水公司可能要将一定量的水从x处送往y处,嘟嘟需要为供水公司找到一条从A至B的水 ...
- P4172 [WC2006]水管局长
题目链接 题目背景 SC 省 MY 市有着庞大的地下水管网络,嘟嘟是 MY 市的水管局长(就是管水管的啦). 题目描述 每天供水公司可能要将一定量的水从 uuu 处送往 vvv 处,嘟嘟需要为供水公司 ...
- P2241 统计方形(数据加强版)-- 70分 python3实现
统计方形(数据加强版) - 洛谷 """P2241 统计方形(数据加强版)-- 70分 python3实现 https://www.luogu.com.cn/proble ...
最新文章
- android TextView 文本里面设置超链接
- c++中的左值与右值
- MyEclipse内存溢出问题
- 本周ASP.NET英文技术文章推荐[10/21 – 10/27]
- “约见”面试官系列之常见面试题之第九十九篇之router和route(建议收藏)
- 【转】mysql 、oracle中char和varchar以及varchar2的区别
- 安装的mysql密码忘了_mysql8安装成功后忘记密码
- 三星S10+顶配版现身GeekBench:搭载Exynos 9820处理器
- sql生成(查询数据的存储过程)代码的存储过程
- 手把手教你配置国内镜像源
- 一元函数积分学的概念与性质
- 方正快速开发平台ES2007数据导入功能问题总结
- iOS-底层原理 19:KVC探索
- PS入门(1-4) CMYK色彩模式
- 服务器之间的无线通讯,无线通讯技术之间的比较 - 常见无线通信(数据)传输技术 你知道哪些...
- 《软技能》读书笔记(上)
- 手机摄像头基础知识-1-缩写篇
- 十二时辰篇:这该死的 996
- 八股文--->Redis
- 菜鸟的最后一篇php教程