题意:

  您有一个无向带权图,您需要支持两种操作。

  1. 询问两个点之间的最大权最小路径。
  2. 删除一条边。

分析:

  众所周知,任意两点间最大权最小路径存在于最小生成树上,所以这道题可以动态维护最小生成树。

  用到的数据结构是可以支持连边和断边的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相关推荐

  1. BZOJ_2594_[Wc2006]水管局长数据加强版_LCT

    BZOJ_2594_[Wc2006]水管局长数据加强版_LCT Description SC省MY市有着庞大的地下水管网络,嘟嘟是MY市的水管局长(就是管水管的啦),嘟嘟作为水管局长的工作就是:每天供 ...

  2. 水管局长数据加强版:lct,时光倒流,最小生成树,边化点

    Description: SC省MY市有着庞大的地下水管网络,嘟嘟是MY市的水管局长(就是管水管的啦),嘟嘟作为水管局长的工作就是:每天供水公司可能要将一定量的水从x处送往y处,嘟嘟需要为供水公司找到 ...

  3. [BZOJ 2594] [Wc2006]水管局长数据加强版 【LCT】

    题目链接:BZOJ - 2594 题目分析 这道题如果没有删边的操作,那么就是 NOIP2013 货车运输,求两点之间的一条路径,使得边权最大的边的边权尽量小. 那么,这条路径就是最小生成树上这两点之 ...

  4. 沉迷Link-Cut tree无法自拔之:[BZOJ2594][Wc2006]水管局长数据加强版

    来自蒟蒻 \(Hero \_of \_Someone\) 的 \(LCT\) 学习笔记 $ $ 这应该算是道套路题吧, 如果将图中的边转换成点, 再将边权变点权, 就可以用 \(LCT\) 来维护了 ...

  5. 2017.10.16 水管局长水管局长数据加强版 思考记录

    在ISA的指点下,彻底理解了lct(以前可能学了假的lct) 这个题不难想,就是倒着加边然后维护链上信息.. 但这题常数巨卡,卡map卡开局不上kruskal卡多余splay卡少用splay. 一般这 ...

  6. P4172 [WC2006]水管局长 LCT维护最小生成树

    \(\color{#0066ff}{ 题目描述 }\) SC 省 MY 市有着庞大的地下水管网络,嘟嘟是 MY 市的水管局长(就是管水管的啦),嘟嘟作为水管局长的工作就是:每天供水公司可能要将一定量的 ...

  7. [洛谷P4172] WC2006 水管局长

    问题描述 SC省MY市有着庞大的地下水管网络,嘟嘟是MY市的水管局长(就是管水管的啦),嘟嘟作为水管局长的工作就是:每天供水公司可能要将一定量的水从x处送往y处,嘟嘟需要为供水公司找到一条从A至B的水 ...

  8. P4172 [WC2006]水管局长

    题目链接 题目背景 SC 省 MY 市有着庞大的地下水管网络,嘟嘟是 MY 市的水管局长(就是管水管的啦). 题目描述 每天供水公司可能要将一定量的水从 uuu 处送往 vvv 处,嘟嘟需要为供水公司 ...

  9. P2241 统计方形(数据加强版)-- 70分 python3实现

    统计方形(数据加强版) - 洛谷 """P2241 统计方形(数据加强版)-- 70分 python3实现 https://www.luogu.com.cn/proble ...

最新文章

  1. android TextView 文本里面设置超链接
  2. c++中的左值与右值
  3. MyEclipse内存溢出问题
  4. 本周ASP.NET英文技术文章推荐[10/21 – 10/27]
  5. “约见”面试官系列之常见面试题之第九十九篇之router和route(建议收藏)
  6. 【转】mysql 、oracle中char和varchar以及varchar2的区别
  7. 安装的mysql密码忘了_mysql8安装成功后忘记密码
  8. 三星S10+顶配版现身GeekBench:搭载Exynos 9820处理器
  9. sql生成(查询数据的存储过程)代码的存储过程
  10. 手把手教你配置国内镜像源
  11. 一元函数积分学的概念与性质
  12. 方正快速开发平台ES2007数据导入功能问题总结
  13. iOS-底层原理 19:KVC探索
  14. PS入门(1-4) CMYK色彩模式
  15. 服务器之间的无线通讯,无线通讯技术之间的比较 - 常见无线通信(数据)传输技术 你知道哪些...
  16. 《软技能》读书笔记(上)
  17. 手机摄像头基础知识-1-缩写篇
  18. 十二时辰篇:这该死的 996
  19. 八股文--->Redis
  20. 菜鸟的最后一篇php教程

热门文章

  1. 程序设计基础(函数)
  2. 如何提高自己的思维能力
  3. “湘潭神女”确属违规提拔任用 “神父”遭疯传
  4. WebRTC使用Linux搭建服务器(二)
  5. VMware、linux虚拟机设置网络实现虚拟机与主机网络互通
  6. 基于php的网上人才招聘系统
  7. 通讯录的编译 c语言,C语言编写—通讯录(小项目)
  8. 推动商业运营 IDC云计算路演至上海金桥
  9. 查看oracle锁定的行,解决oracle的行锁定问题
  10. 计算机中绝对值用哪个函数,Excel中的绝对值函数具体该如何使用呢?