来自FallDream的博客,未经允许,请勿转载,谢谢。


简要题意:给定一张n个点m条边的图,有边权,需要支持两个操作 1)删除一条边2)求两点之间边权最大值的最小值   n和操作次数不超过10^5,m<=10^6
题解:很显然要你维护的是一个最小生成树qaq
然后删边太难了,考虑倒过来加边,用边权lct维护最小生成树。每个点维护向父亲和偏爱儿子的连边的编号,还有他所在的splay的最左边和最右边的那条边(不懂边权lct可以自行百度)
假设你要插入边u->v,如果它们不连通,直接插入。不然的话,如果u->v的路径上的边权的最大值超过了这条边的边权,删掉最大的那条边,加入这条边就行了。
lct常数巨大  所以一开始把没被删除的边插入的时候不能lct,要用kruscal,不然T的飞起。
#include<iostream>
#include<cstdio>
#include<algorithm>
#define MN 100000
#define INF 2000000000
#define getchar() (*S++)
using namespace std;
char B[1<<26],*S=B;
inline int read()
{int x = 0 , f = 1; char ch = getchar();while(ch < '0' || ch > '9'){ if(ch == '-') f = -1;  ch = getchar();}while(ch >= '0' && ch <= '9'){x = x * 10 + ch - '0';ch = getchar();}return x * f;
}int n,m,Q,rk[MN*10+5],fa[MN+5],qu[MN+5],top,c[MN+5][2],mx[MN+5],s[MN+5],p[MN+5],f[MN+5],L[MN+5],R[MN+5],ans[MN+5];
bool rev[MN+5],mark[MN*10+5];
struct edge{int from,to,w,num;bool operator<(const edge&b)const{return from==b.from?to<b.to:from<b.from;}
}e[MN*10+5];
struct ques{int kind,x,y;}q[MN+5];inline bool isroot(int x){return c[fa[x]][0]!=x&&c[fa[x]][1]!=x;}
inline void pushdown(int x)
{if(rev[x]){int l=c[x][0],r=c[x][1];rev[l]^=1;rev[r]^=1;rev[x]^=1;swap(c[x][0],c[x][1]);swap(L[l],R[l]);swap(f[l],p[l]);swap(L[r],R[r]);swap(f[r],p[r]); }
}
inline void U(int&x,int y){if(e[x].w<e[y].w) x=y;}
inline void update(int x)
{mx[x]=(e[f[x]].w>e[p[x]].w)?f[x]:p[x];L[x]=f[x];R[x]=p[x];int l=c[x][0],r=c[x][1];if(l) L[x]=L[l],U(mx[x],mx[l]),U(mx[x],p[l]);if(r) R[x]=R[r],U(mx[x],mx[r]),U(mx[x],f[r]);
}void rotate(int x)
{int y=fa[x],z=fa[y],l=c[y][1]==x,r=l^1;if(!isroot(y)) c[z][c[z][1]==y]=x;fa[x]=z;fa[y]=x;fa[c[x][r]]=y;c[y][l]=c[x][r];c[x][r]=y;update(y);update(x);
}void splay(int x)
{qu[top=1]=x;for(int t=x;!isroot(t);t=fa[t]) qu[++top]=fa[t];for(;top;--top) pushdown(qu[top]);for(;!isroot(x);rotate(x))if(!isroot(fa[x])) rotate((c[fa[fa[x]]][1]==fa[x]^c[fa[x]][1]==x)?x:fa[x]);
}void access(int x)
{for(int y=0;x;x=fa[y=x])splay(x),c[x][1]=y,p[x]=L[y],update(x);
}void link(int x,int y,int z)
{access(x);splay(x);rev[x]^=1;swap(f[x],p[x]);swap(L[x],R[x]); access(y);fa[c[y][1]=x]=y;f[x]=p[y]=z;update(x);update(y);
}void cut(int x,int y)
{access(x);splay(x);rev[x]^=1;swap(f[x],p[x]);swap(L[x],R[x]); access(y);splay(y);c[y][0]=fa[x]=f[y]=p[x]=0;update(x);update(y);
}void ins(int id)
{int x=e[id].from,y=e[id].to,z=e[id].w;access(x);splay(x);rev[x]^=1;swap(f[x],p[x]);swap(L[x],R[x]); access(y);splay(y);if(isroot(x)) link(x,y,id);else if(e[mx[y]].w>z) cut(e[mx[y]].from,e[mx[y]].to),link(x,y,id);
}inline int getfa(int x){return !s[x]?x:s[x]=getfa(s[x]);}
bool cmp(int x,int y){return e[x].w<e[y].w;}
int main()
{fread(B,1,1<<26,stdin);e[0].w=-INF;n=read();m=read();Q=read();for(register int i=1;i<=m;i++) {e[i].from=read(),e[i].to=read(),e[i].w=read();if(e[i].from>e[i].to) swap(e[i].from,e[i].to);}sort(e+1,e+m+1);for(int i=1;i<=m;i++) rk[i]=i;for(register int i=1;i<=Q;i++){q[i].kind=read();q[i].x=read();q[i].y=read();if(q[i].kind==2) {if(q[i].x>q[i].y) swap(q[i].x,q[i].y);q[i].x=lower_bound(e+1,e+m+1,(edge){q[i].x,q[i].y,0})-e;    mark[q[i].x]=1;}}sort(rk+1,rk+m+1,cmp);for(register int i=1;i<=m;i++)if(!mark[rk[i]]){int x=getfa(e[rk[i]].from),y=getfa(e[rk[i]].to);if(x!=y) s[x]=y,link(e[rk[i]].from,e[rk[i]].to,rk[i]);}for(register int i=Q;i;i--)if(q[i].kind==2) ins(q[i].x);else{int x=q[i].x,y=q[i].y;access(x);splay(x);rev[x]^=1;swap(f[x],p[x]);swap(L[x],R[x]); access(y);splay(y);ans[i]=e[mx[y]].w;}for(register int i=1;i<=Q;i++)if(q[i].kind<2) printf("%d\n",ans[i]);return 0;
}

转载于:https://www.cnblogs.com/FallDream/p/bzoj2594.html

[bzoj2594][Wc2006]水管局长数据加强版相关推荐

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

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

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

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

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

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

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

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

  5. BZOJ2594 水管局长数据加强版LCT

    题意: 您有一个无向带权图,您需要支持两种操作. 询问两个点之间的最大权最小路径. 删除一条边. 分析: 众所周知,任意两点间最大权最小路径存在于最小生成树上,所以这道题可以动态维护最小生成树. 用到 ...

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

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

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

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

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

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

  9. P4172 [WC2006]水管局长

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

  10. 【BZOJ2594】水管局长加强版,LCT+并查集+二分查找位置

    Time:2016.05.10 Author:xiaoyimi 转载注明出处谢谢 传送门 思路: LCT维护路径最小值 倒叙处理询问,就相当于往图里面加边. 实时维护最小值,即最小生成树,可以参照魔法 ...

最新文章

  1. mac os x常用快捷键及用法
  2. gprs发送信号对方如何接收_和接收缓冲区比较:Netty发送缓冲区是如何设计的,why?...
  3. Vivado Fir Ip核动态更改滤波器系数的两种方法
  4. 变量,作用域,和内存问题
  5. python中x=x+1的读法-python中xrange和range的区别
  6. Python爬虫-利用代理IP访问网页(requests)
  7. wifi rssi 计算 距离_WiFi和WLAN是一样的?真相在这里~别再傻傻分不清了
  8. Python之操作HBASE数据库
  9. 写了4年博客,我终于也出了一本书。
  10. ionic4 ts跳转传值 this.navController.navigateForward
  11. Netty工作笔记0041---Netty入门--服务端2
  12. 国内的优秀HTML5前端开发框架
  13. linux文件及文件夹权限
  14. 【Caffe实践】基于CNN的性别、年龄识别
  15. 【前端——补充学习】解决emos项目报错、路由、组件
  16. PLC梯形图设计全自动洗衣机S7-1200博途以及PLC仿真实现之 1. 创建新工程
  17. C++中的仿函数(functors)和仿函数适配器(adapter function)
  18. python 视频文件格式和分辨率转换
  19. Windows 下Apache ftpServer安装和配置
  20. 用 Python 制作“会跳舞”的动态图表

热门文章

  1. kali文件重命名_硬核教程,必看!「网络安全入门」四、文件上传漏洞
  2. xgboost算法详解
  3. 基于sklearn和keras的数据切分与交叉验证
  4. 2019-02-26-GCN资料
  5. matcaffe编译与测试
  6. 图像梯度-Sobel算子
  7. 百度地图依赖包php,调用百度地图
  8. mysql加begin报错,MySQL存储过程例子,不能在if else里面用begin end否则会报错Error Code:1064解决...
  9. redis技术分享ppt_技术分享丨华为鲲鹏架构Redis知识二三事
  10. c++歌手类代码_安卓资源ID修改-游戏发行-切包过程中的R类和Public.xml