因为C是不断变化的而且C是和点权相关和边权无关 所以我们可以MCMF但是MCMF的时候不能与C相关

再分析问题 我们可以认为每条路径S->T只覆盖T这个终点 因为题目中说了如果Si != Ti 要多付出 C的代价

假设我们走过的路径形成了一个环则刚好 边数=点数 覆盖完了

如果走过的路径不是一个环 则还有起点没有覆盖 此时我们可以把它当作没有途径的城市 给他补偿 同样为C

所以我们把原图拆成左边出点 右边入点 传递闭包后建图

这样每次MCMF增广的代价是不递减的 并且每增广一次多覆盖一个点 所以我们把每次增广的代价放到一个数组里面

每次询问我们二分C在数组里的位置,在C之前的点我们利用路径覆盖 在C及C之后的点我们用C去补偿它

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define ll long long
  4. #define MAX 255
  5. inline int read() {
  6. int x = ;
  7. bool t = false;
  8. char ch = getchar();
  9. while ((ch < '' || ch > '') && ch != '-')
  10. ch = getchar();
  11. if (ch == '-')
  12. t = true, ch = getchar();
  13. while (ch <= '' && ch >= '')
  14. x = x * + ch - , ch = getchar();
  15. return t ? -x : x;
  16. }
  17. int val[MAX], sum[MAX], tot;
  18. namespace MCMF {
  19. const int MAXM = , MAXN = ;
  20. struct Line {
  21. int v, next, w, fy;
  22. } e[MAXM];
  23. int h[MAXN], cnt = ;
  24. inline void Add(int u, int v, int w, int fy) {
  25. e[cnt] = (Line) {
  26. v, h[u], w, fy
  27. };
  28. h[u] = cnt++;
  29. e[cnt] = (Line) {
  30. u, h[v], , -fy
  31. };
  32. h[v] = cnt++;
  33. }
  34. int dis[MAXN], pe[MAXN], pv[MAXN], Cost, Flow;
  35. bool vis[MAXN];
  36. queue<int> Q;
  37. int S = , T = MAXN - ;
  38. bool SPFA() {
  39. memset(dis, , sizeof(dis));
  40. dis[S] = ;
  41. Q.push(S);
  42. vis[S] = true;
  43. while (!Q.empty()) {
  44. int u = Q.front();
  45. Q.pop();
  46. for (int i = h[u]; i; i = e[i].next) {
  47. int v = e[i].v;
  48. if (!e[i].w)
  49. continue;
  50. if (dis[u] + e[i].fy < dis[v]) {
  51. dis[v] = dis[u] + e[i].fy;
  52. pe[v] = i, pv[v] = u;
  53. if (!vis[v])
  54. vis[v] = true, Q.push(v);
  55. }
  56. }
  57. vis[u] = false;
  58. }
  59. if (dis[T] >= 1e9)
  60. return false;
  61. int flow = 1e9;
  62. for (int i = T; i != S; i = pv[i])
  63. flow = min(flow, e[pe[i]].w);
  64. for (int i = T; i != S; i = pv[i])
  65. e[pe[i]].w -= flow, e[pe[i] ^ ].w += flow;
  66. Flow += flow;
  67. Cost += dis[T] * flow;
  68. val[++tot] = dis[T] * flow;
  69. sum[tot] = sum[tot - ] + val[tot];
  70. return true;
  71. }
  72. }
  73. using namespace MCMF;
  74. int n, m, q, g[MAX][MAX];
  75. int main() {
  76. n = read();
  77. m = read();
  78. q = read();
  79. memset(g, , sizeof(g));
  80. for (int i = ; i <= n; ++i)
  81. g[i][i] = ;
  82. for (int i = , u, v; i <= m; ++i)
  83. u = read(), v = read(), g[u][v] = min(read(), g[u][v]);
  84. for (int k = ; k <= n; ++k)
  85. for (int i = ; i <= n; ++i)
  86. for (int j = ; j <= n; ++j)
  87. g[i][j] = min(g[i][j], g[i][k] + g[k][j]);
  88. for (int i = ; i <= n; ++i)
  89. for (int j = ; j <= n; ++j)
  90. if (i ^ j)
  91. Add(i, j + n, , g[i][j]);
  92. for (int i = ; i <= n; ++i)
  93. Add(S, i, , ), Add(i + n, T, , );
  94. while (SPFA());
  95. while (q--) {
  96. int C = read(), l = , r = tot, ret = ;
  97. while (l <= r) {
  98. int mid = (l + r) >> ;
  99. if (val[mid] < C)
  100. l = mid + , ret = mid;
  101. else
  102. r = mid - ;
  103. }
  104. printf("%d\n", sum[ret] + (n - ret)*C);
  105. }
  106. return ;
  107. }

【BZOJ3691】游行 最小可相交路径覆盖转化的更多相关文章

  1. POJ 2594 Treasure Exploration 最小可相交路径覆盖

    最小路径覆盖 DAG的最小可相交路径覆盖: 算法:先用floyd求出原图的传递闭包,即如果a到b有路径,那么就加边a->b.然后就转化成了最小不相交路径覆盖问题. 这里解释一下floyd的作用如 ...

  2. POJ2594 Treasure Exploration[DAG的最小可相交路径覆盖]

    Treasure Exploration Time Limit: 6000MS   Memory Limit: 65536K Total Submissions: 8301   Accepted: 3 ...

  3. POJ 2594 Treasure Exploration(最小可相交路径覆盖)题解

    题意:有n个点,m条单向边,每个机器人能沿着单向边走,能重复经过一个点,问最少几个机器人走遍n个点 思路:原来以前学的都是不能相交的算法....可相交的做法是跑Floyd把能到达的都加上边,然后跑最小 ...

  4. FJUT3591 侦测到在途的聚变打击(最小不可相交路径覆盖)题解

    题意:给你n个点,点间m条路,给出在每条路要走的时间.现在有q个任务,要摧毁q个点,每次提供ci和ti表示在时间ti摧毁点ci(必须正好在时间ti才能摧毁),每个点可能需要多次摧毁(同一时间能在同一个 ...

  5. 有向无环图(DAG)的最小路径覆盖(转)

    DAG的最小路径覆盖 定义:在一个有向图中,找出最少的路径,使得这些路径经过了所有的点. 最小路径覆盖分为最小不相交路径覆盖和最小可相交路径覆盖. 最小不相交路径覆盖:每一条路径经过的顶点各不相同.如 ...

  6. 有向无环图(DAG)的最小路径覆盖

    DAG的最小路径覆盖 定义:在一个有向图中,找出最少的路径,使得这些路径经过了所有的点. 最小路径覆盖分为最小不相交路径覆盖和最小可相交路径覆盖. 最小不相交路径覆盖:每一条路径经过的顶点各不相同.如 ...

  7. HDU 3861 The King’s Problem 最小路径覆盖(强连通分量缩点+二分图最大匹配)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3861 最小路径覆盖的一篇博客:https://blog.csdn.net/qq_39627843/ar ...

  8. POJ 2594 (传递闭包 + 最小路径覆盖)

    题目链接: POJ 2594 题目大意:给你 1~N 个点, M 条有向边.问你最少需要多少个机器人,让它们走完所有节点,不同的机器人可以走过同样的一条路,图保证为 DAG. 很明显是 最小可相交路径 ...

  9. Air Raid POJ - 1422 【有向无环图(DAG)的最小路径覆盖【最小不相交路径覆盖】 模板题】

    Consider a town where all the streets are one-way and each street leads from one intersection to ano ...

随机推荐

  1. 【嵌入式硬件Esp32】ESP32 正确下载姿势

    程序的正确下载步骤,以8M flash为例子: 一.硬件连接 ESP32 的运行状态主要由 GPIO0 决定 二.ESP32 Flash 地址配置 ESP32 在编译时,通过 make menucon ...

  2. mac install azure-cli

    安装 CLI 时,可以先更新 brew 存储库信息,然后运行 install 命令: brew update && brew install azure-cli 更新: brew up ...

  3. nlp算法

    人工智能算法大体上来说可以分类两类:基于统计的机器学习算法(Machine Learning)和深度学习算法(Deep Learning) 总的来说,在sklearn中机器学习算法大概的分类如下: 1 ...

  4. 数组模拟循环队列(java实现)

    1.front变量的含义:front就指向队列的第一个元素,也就是说arr[front]就是队列的第一个元素front的初始值=0. 2.rear变量的含义:rear指向队列的最后一个元素的后一个位置 ...

  5. C++语言动态创建对象

    焦头烂额的考试月终于过去了,终于有时间能停下来思考记录一下这一个月学过的东西,首先先总结一下,在自己仿写魂斗罗游戏时遇见的问题之一,人物在移动的时候如何去判断什么时候掉入水中显示水中画面,什么时候敌人 ...

  6. Scratch编程:躲开鲨鱼(五)

    “ 上节课的内容全部掌握了吗?反复练习了没有,编程最好的学习方法就是练习.练习.再练习.一定要记得多动手.多动脑筋哦~~” 01 — 游戏介绍 这是一款简单的小游戏,实现了用鼠标控制一条小海星在水里游 ...

  7. 括号匹配问题 —— Deque双端队列解法

    题目: 给定一个只包括 '(',')','{','}','[',']'?的字符串,判断字符串是否有效. 有效字符串需满足: 左括号必须用相同类型的右括号闭合.左括号必须以正确的顺序闭合.注意空字符串可 ...

  8. 使用winsw将springboot打包的jar注册系统本地服务

    1.下载winsw 下载地址:https://github.com/kohsuke/winsw/releases 我这里下载的是2.3.0版. 下载sample-minimal.xml和WinSW.N ...

  9. 关于Windows下的访问控制模型

    在探索Windows操作系统的过程中,发现很多有意思 的东西. Windows下的访问控制模型也是我在Github上浏览代码时,无意中发现的. 项目地址 https://github.com/Krut ...

  10. 回忆一下Node(随时更改,想到什么写什么)

    什么是Node? Node.js 是一个基于Chrome V8 引擎的JavaScript运行环境 Node.js使用了一个事件驱动.非阻塞式I/O的模型,使其轻量又高效 事件驱动: 任务执行,发布者 ...