题目传送门

  传送门

题目大意

  $m$只鼹鼠有$n$个巢穴,$n - 1$条长度为$1$的通道将它们连通且第$i(i > 1)$个巢穴与第$\left\lfloor \frac{i}{2}\right\rfloor$个巢穴连通。第$i$个巢穴在最终时允许$c_i$只醒来的鼹鼠最终停留在这。已知第$i$只鼹鼠在第$p_i$个巢穴睡觉。要求求出对于每个满足$1 \leqslant k \leqslant n$的$k$,如果前$k$只鼹鼠醒来,最小的移动距离的总和。

  考虑费用流的建图和暴力做法,把原图的边容量设为无限大,费用设为1(每条无向边要拆成两条),每个点再向汇点连一条边,容量为$c_i$,费用为0。

  对于每次源点向$p_i$增广1单位的流量。

  显然这样会超时,考虑优化费用流。

  显然有:

  • 每次增广的路径一定是一条简单路径
  • 对于原图的一条无向边,它两个方向的边不会同时有流量(走另外一条弧的反向弧显然可以减少费用)

  那么每次枚举路径的LCA,对于每个点记录一下$f_i$表示从$i$走到子树内的任意一个点的最短距离。

  显然每次更新边权后很容易能够维护$f$。时间复杂度$O(n\log n)$。

Code

  1. /**
  2. * Codeforces
  3. * Gym#101190M
  4. * Accepted
  5. * Time: 108ms
  6. * Memory: 2200k
  7. */
  8. #include <iostream>
  9. #include <cstdlib>
  10. #include <cstdio>
  11. #ifndef WIN32
  12. #define Auto "%lld"
  13. #else
  14. #define Auto "%I64d"
  15. #endif
  16. using namespace std;
  17. typedef bool boolean;
  18.  
  19. #define ll long long
  20.  
  21. const signed ll llf = (signed ll) (~0ull >> );
  22. const signed int inf = (signed) (~0u >> );
  23. const int N = ;
  24.  
  25. #define pii pair<int, int>
  26.  
  27. pii operator + (pii a, int b) {
  28. return pii(a.first + b, a.second);
  29. }
  30.  
  31. int n, m;
  32. int w[N], c[N];
  33. pii fd[N];
  34.  
  35. inline void init() {
  36. scanf("%d%d", &n, &m);
  37. for (int i = ; i <= n; i++) {
  38. scanf("%d", c + i);
  39. }
  40. }
  41.  
  42. int value(int p, int dir) { // up : +1, down : -1
  43. int prod = w[p] * dir;
  44. return (prod >= ) ? () : (-);
  45. }
  46.  
  47. void __update(int p) {
  48. fd[p] = pii(inf * (!c[p]), p);
  49. if ((p << ) <= n && fd[p << ].first != inf)
  50. fd[p] = min(fd[p], fd[p << ] + value(p << , -));
  51. if ((p << ) < n && fd[p << | ].first != inf)
  52. fd[p] = min(fd[p], fd[p << | ] + value(p << | , -));
  53. }
  54.  
  55. int update(int s) {
  56. int val = fd[s].first, g = s, v = fd[s].second, len = ;
  57. for (int p = s, d = (p & ), q, cmp; len += value(p, ), p >>= ; d = p & ) {
  58. q = p << | (d ^ );
  59. if (q <= n && (cmp = fd[q].first + value(q, -) + len) < val)
  60. val = cmp, g = p, v = fd[q].second;
  61. if (c[p] && len < val)
  62. val = len, g = v = p;
  63. }
  64. c[v]--;
  65. for (int p = s; p != g; p >>= ) {
  66. w[p]++;
  67. __update(p);
  68. }
  69. for (int p = v; p != g; p >>= ) {
  70. w[p]--;
  71. __update(p);
  72. }
  73. for (int p = g; p; p >>= )
  74. __update(p);
  75. // cerr << s << " " << v << '\n';
  76. return val;
  77. }
  78.  
  79. inline void solve() {
  80. for (int i = ; i <= n; i++)
  81. fd[i] = pii(inf * (!c[i]), i);
  82. for (int i = n; i > ; i--)
  83. fd[i >> ] = min(fd[i >> ], fd[i] + );
  84.  
  85. int x;
  86. ll res = ;
  87. while (m--) {
  88. scanf("%d", &x);
  89. res += update(x);
  90. printf(Auto" ", res);
  91. }
  92. }
  93.  
  94. int main() {
  95. freopen("mole.in", "r", stdin);
  96. freopen("mole.out", "w", stdout);
  97. init();
  98. solve();
  99. return ;
  100. }

Codeforces Gym 101190M Mole Tunnels - 费用流的更多相关文章

  1. Codeforces 362E Petya and Pipes 费用流建图

    题意: 给一个网络中某些边增加容量,增加的总和最大为K,使得最大流最大. 费用流:在某条边增加单位流量的费用. 那么就可以2个点之间建2条边,第一条给定边(u,v,x,0)这条边费用为0 同时另一条边 ...

  2. Codeforces Gym 100203I I WIN 最大流

    原题链接:http://codeforces.com/gym/100203/attachments/download/1702/statements.pdf 题解 首先寻找每个I,然后枚举形状,如果匹 ...

  3. CodeForces - 884F :Anti-Palindromize(贪心&费用流)

    A string a of length m is called antipalindromic iff m is even, and for each i (1 ≤ i ≤ m) ai ≠ am - ...

  4. Codeforces Gym 100002 E "Evacuation Plan" 费用流

    "Evacuation Plan" Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/10 ...

  5. 【BZOJ4849】[Neerc2016]Mole Tunnels 模拟费用流

    [BZOJ4849][Neerc2016]Mole Tunnels Description 鼹鼠们在底下开凿了n个洞,由n-1条隧道连接,对于任意的i>1,第i个洞都会和第i/2(取下整)个洞间 ...

  6. BZOJ4849[Neerc2016]Mole Tunnels——模拟费用流+树形DP

    题目描述 鼹鼠们在底下开凿了n个洞,由n-1条隧道连接,对于任意的i>1,第i个洞都会和第i/2(取下整)个洞间有一条隧 道,第i个洞内还有ci个食物能供最多ci只鼹鼠吃.一共有m只鼹鼠,第i只 ...

  7. bzoj 4849: [Neerc2016]Mole Tunnels【模拟费用流】

    参考:https://www.cnblogs.com/CQzhangyu/p/6952371.html 费用流很简单,考虑但是会T. 考虑费用流的本质,流一次需要要找一个能够从当前点到达的距离最小的点 ...

  8. BZOJ 4849 [NEERC2016]Mole Tunnels (模拟费用流)

    题目链接 https://www.lydsy.com/JudgeOnline/problem.php?id=4849 题解 其实也是模拟费用流,但是这道题和一般的题目不一样,这道题是在一个完全二叉树上 ...

  9. P6122-[NEERC2016]Mole Tunnels【模拟费用流】

    正题 题目链接:https://www.luogu.com.cn/problem/P6122 题目大意 给出\(n\)个点的一棵满二叉树,每个点有容量\(c_i\),\(m\)次从\(p_i\)处加一 ...

随机推荐

  1. tomcat 启动方式

    <?xml version="1.0" encoding="UTF-8"?><Context docBase="wexin" ...

  2. Luogu5155 [USACO18DEC]Balance Beam

    题目链接:洛谷 这道题看起来是个期望题,但是其实是一道计算几何(这种题太妙了) 首先有一个很好的结论,在一个长度为$L$的数轴上,每次从$x$处出发,不停地走,有$\frac{x}{L}$的概率从右端 ...

  3. Zookeeper节点增删改查与集群搭建(笔记)

    1.上传文件目录说明 上传的文件一般放在 /home/下 安装文件一般在 /usr/local/下 2. 安装zookeeper 2.1将zookeeper-3.4.11.tar.gz拷贝到/home ...

  4. Socket断开不报错(Java)

    网上看了很多关于Socket的Demo,用起来挺好用也简单,不过都在断开连接时,都没有做好相关处理,导致每次主动断开时,会报错 如: java.net.SocketException: Socket ...

  5. 2019春第五周作业Compile Summarize

    这个作业属于哪个课程 C语言程序设计II 这个作业要求在哪里 在这里 我在这个课程的目标是 能够精通关于数组内部运作原理 这个作业在哪个具体方面帮助我实现目标 如何输出一行的连续字符 参考文献与网址 ...

  6. 2019CCF-GAIR全球人工智能与机器人峰会于7月在深圳召开

    全球人工智能与机器人峰会(CCF-GAIR)是由中国计算机学会(CCF)主办,雷锋网.香港中文大学(深圳)承办,得到了深圳市政府的大力指导,是国内人工智能和机器人学术界.工业界及投资界三大领域的顶级交 ...

  7. MFC关于.rc文件 .rc2文件

    .rc文件和.rc2文件 c和rc2都是资源文件,包含了应用程序中用到的所有的资源. 两者不同在于:rc文件中的资源可以直接在VC集成环境中以可视化的方法进行编辑和修改; 而rc2中的资源不能在VC的 ...

  8. Javascript扩展String.prototype实现格式金额、格式时间、字符串连接、计算长度、是否包含、日期计算等功能

    <script src="Js/jquery-3.1.1.min.js"></script> <script type="text/java ...

  9. 对int类型的数据,如何让获取长度

    下面为大家写一个列子   int a = 124;<br> Integer a1 = a;//转换为包装类Integer<br> System.out.println(a1.t ...

  10. spark-shell的Scala的一些方法详解

    Tom,DataBase,80 Tom,Algorithm,50 Tom,DataStructure,60 Jim,DataBase,90 Jim,Algorithm,60 Jim,DataStruc ...