题目链接 洛谷(COGS上也有)

不想去做加强版了。。(其实处理一下矩阵就好了)

题意: 有一张图,求一条x->y的路径,使得路径上最长边尽量短并输出它的长度。会有<=5000次删边。

这实际上就是动态地维护MST。用LCT维护MST,路径询问也能直接查询,每次删边看这条边是否在MST上。

只有1000个点!边直接矩阵存。

而且删边次数很少,于是最初想的是每次删边用堆优化Prim O(nlogn)重新求一遍MST。但是\(5000*1000*10=5e7\)。。(也许行吧)

日常删边改成加边,离线即可。加边时MST上的求路径Max,看是否需要Cut,重新Link.(正序的话还要找一遍没被删的连接两集合的最小边)

  1. #include <cstdio>
  2. #include <cctype>
  3. #include <algorithm>
  4. //#define gc() getchar()
  5. #define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
  6. #define MAXIN (200000)
  7. const int N=1005,M=1e5+5,S=N+M;//虽然维护的是MST但大小还是要M的。。当然可以记录每条树边并循环利用,以后再写吧。。
  8. int n,m,type[M],ff[N],qx[M],qy[M],id[N][N],Ans[M];
  9. char IN[MAXIN],*SS=IN,*TT=IN;
  10. bool ban[M];
  11. struct Edge{
  12. int fr,to,val;
  13. Edge() {}
  14. Edge(int f,int t,int v):fr(f),to(t),val(v) {}
  15. bool operator <(const Edge &a)const{
  16. return val<a.val;
  17. }
  18. }e[M];
  19. namespace LCT
  20. {
  21. #define lson son[x][0]
  22. #define rson son[x][1]
  23. int pos[S],val[S],son[S][2],fa[S],sk[S];
  24. bool rev[S];
  25. inline int Get(int x,int y){
  26. return val[x]>val[y]?x:y;
  27. }
  28. inline void Update(int x){
  29. pos[x]=Get(x,Get(pos[lson],pos[rson]));//是左右儿子的pos!又一次写错。。
  30. }
  31. inline bool n_root(int x){
  32. return son[fa[x]][0]==x||son[fa[x]][1]==x;
  33. }
  34. inline void Rev(int x){
  35. std::swap(lson,rson), rev[x]^=1;
  36. }
  37. void PushDown(int x){
  38. if(rev[x]) Rev(lson),Rev(rson),rev[x]=0;
  39. }
  40. void Rotate(int x)
  41. {
  42. int a=fa[x],b=fa[a],l=son[a][1]==x,r=l^1;
  43. if(n_root(a)) son[b][son[b][1]==a]=x;
  44. if(son[x][r]) fa[son[x][r]]=a;
  45. fa[a]=x, fa[x]=b, son[a][l]=son[x][r], son[x][r]=a;
  46. Update(a);
  47. }
  48. void Splay(int x)
  49. {
  50. int t=1,a=x; sk[1]=x;
  51. while(n_root(a)) sk[++t]=a=fa[a];
  52. while(t) PushDown(sk[t--]);
  53. while(n_root(x))
  54. {
  55. if(n_root(a=fa[x])) Rotate(son[a][1]==x^son[fa[a]][1]==a?x:a);
  56. Rotate(x);
  57. }
  58. Update(x);
  59. }
  60. void Access(int x){
  61. for(int pre=0; x; x=fa[pre=x])
  62. Splay(x), rson=pre, Update(x);
  63. }
  64. void Make_root(int x){
  65. Access(x), Splay(x), Rev(x);
  66. }
  67. void Split(int x,int y){
  68. Make_root(x), Access(y), Splay(y);
  69. }
  70. int Find_root(int x)
  71. {
  72. Access(x), Splay(x);
  73. while(lson) x=lson;
  74. return x;
  75. }
  76. void Link(int x){//在合法的情况下Find_root()并不是必须的(不维护子树信息的话?)
  77. Make_root(e[x].to), fa[fa[e[x].to]=x+N]=e[x].fr;
  78. val[x+N]=e[x].val, Update(x+N);
  79. }
  80. void Cut(int x){//注意这的编号
  81. Access(e[x-N].to), Splay(x), lson=rson=fa[lson]=fa[rson]=0;
  82. }
  83. }
  84. using namespace LCT;
  85. inline int read()
  86. {
  87. int now=0;register char c=gc();
  88. for(;!isdigit(c);c=gc());
  89. for(;isdigit(c);now=now*10+c-'0',c=gc());
  90. return now;
  91. }
  92. int Get_fa(int x){
  93. return x==ff[x]?x:ff[x]=Get_fa(ff[x]);
  94. }
  95. int main()
  96. {
  97. n=read(),m=read();int Q=read();
  98. for(int x,y,i=1; i<=m; ++i) x=read(),y=read(),e[i]=Edge(x,y,read());
  99. std::sort(e+1,e+1+m);//先排序再编号!
  100. for(int i=1; i<=m; ++i) id[e[i].fr][e[i].to]=id[e[i].to][e[i].fr]=i;
  101. for(int i=1; i<=Q; ++i)
  102. {
  103. type[i]=read(),qx[i]=read(),qy[i]=read();
  104. if(type[i]==2) ban[id[qx[i]][qy[i]]]=1;
  105. }
  106. for(int i=1; i<=n; ++i) ff[i]=i;
  107. for(int t,x,y,k=0,i=1; i<=m; ++i)
  108. if(!ban[t=id[x=e[i].fr][y=e[i].to]] && Get_fa(x)!=Get_fa(y))
  109. {//不需要记r1,r2
  110. ff[ff[x]]=ff[y], Link(t);
  111. if(++k==n) break;
  112. }
  113. int cnt=0;
  114. for(int i=Q,x,y,t; i; --i)
  115. {
  116. Split(x=qx[i],y=qy[i]);
  117. if(type[i]==1) Ans[++cnt]=val[pos[y]];
  118. else if(t=id[x][y],val[pos[y]]>e[t].val){
  119. Cut(pos[y]), Link(t);
  120. }
  121. }
  122. while(cnt) printf("%d\n",Ans[cnt--]);
  123. return 0;
  124. }

洛谷.4172.[WC2006]水管局长(LCT Kruskal)的更多相关文章

  1. 洛谷4172 WC2006水管局长(LCT维护最小生成树)

    这个题和魔法森林感觉有很相近的地方啊 同样也是维护一个类似最大边权最小的生成树 但是不同的是,这个题是有\(cut\)和询问,两种操作.... 这可如何是好啊? 我们不妨倒着来考虑,假设所有要\(cu ...

  2. 洛谷 4172 [WC2006]水管局长

    [题解] 我们把操作倒过来做,就变成了加边而不是删边.于是用LCT维护动态加边的最小生成树就好了.同样要注意把边权变为点权. #include<cstdio> #include<al ...

  3. 洛谷P4172 [WC2006]水管局长 (LCT,最小生成树)

    洛谷题目传送门 思路分析 在一个图中,要求路径上最大边边权最小,就不难想到最小生成树.而题目中有删边的操作,那肯定是要动态维护啦.直接上LCT维护边权最小值(可以参考一下蒟蒻的Blog) 这时候令人头 ...

  4. 洛谷P4172 [WC2006]水管局长(lct求动态最小生成树)

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

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

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

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

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

  7. luogu P4172 [WC2006]水管局长 LCT维护动态MST + 离线

    Code: #include<bits/stdc++.h> #define maxn 1200000 #define N 120000 using namespace std; char ...

  8. 【洛谷P4172】水管局长

    题目大意:给定 N 个点,M 条边的无向图,支持两种操作:动态删边和查询任意两点之间路径上边权的最大值最小是多少. 题解: 引理:对原图求最小生成树,可以保证任意两点之间的路径上边权的最大值取得最小值 ...

  9. P4172 [WC2006]水管局长(LCT)

    P4172 [WC2006]水管局长 LCT维护最小生成树,边权化点权.类似 P2387 [NOI2014]魔法森林(LCT) 离线存储询问,倒序处理,删边改加边. #include<iostr ...

随机推荐

  1. register 用法注意与深入--【sky原创】

    register 用法注意与深入:   gcc -o test  test.c   这样编译的话会报错的,因为寄存器变量是不能取地址的,只有内存的变量才能取地址 寄存器变量取的是虚拟地址   #inc ...

  2. springboot系列十四、自定义实现starter

    一.starter的作用 当我们实现了一个组建,希望尽可能降低它的介入成本,一般的组建写好了,只要添加spring扫描路径加载spring就能发挥作用.有个更简单的方式扫描路径都不用加,直接引入jar ...

  3. Python3学习笔记15-迭代器与生成器

    生成器 如果创建一个有很多元素的列表,但是只需要访问前几个元素,后面的元素占着的空间就白白浪费了 在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间. 在Pytho ...

  4. InetAddress问题

    InetAddress的方法 当输入InetAddress.getByAddress(new byte[]{127.0.0.1})的时候不会报错, 但是ip的各段值是0-255,当new byte[] ...

  5. java多线程快速入门(十一)

    在方法上面加synchonizd用的是this锁 package com.cppdy; class MyThread7 implements Runnable { private Integer ti ...

  6. CNN卷积核计算

    作者:十岁的小男孩 目录 单层卷积核计算 三维卷积核计算 Padding=Valid&&Same 总结

  7. 【C++】类前置声明范例

    • 在编写C++程序的时候,偶尔需要用到前置声明(Forward declaration).下面的程序中,带注释的那行就是类B的前置说明.这是必须的,因为类A中用到了类B,而类B的声明出现在类A的后面 ...

  8. 7za的压缩与解压

    2.1 解压缩7z文件 7za x phpMyAdmin-3.3.8.1-all-languages.7z -r -o./ 参数含义: x  代表解压缩文件,并且是按原始目录树解压(还有个参数 e 也 ...

  9. poj 3461 (模式串T在主串S中出现的次数)

    求模式串在主串中出现的次数Sample Input 3BAPCBAPCAZAAZAZAZAVERDIAVERDXIVYERDIANSample Output 130 #include <iost ...

  10. HDU 3980 (SG 环变成链 之前的先手变成后手)

    题意 两个人在一个由 n 个玻璃珠组成的一个圆环上玩涂色游戏,游戏的规则是: 1.每人一轮,每轮选择一个长度为 m 的连续的.没有涂过色的玻璃珠串涂色 2.不能涂色的那个人输掉游戏 Aekdycoin ...