HDU6582链接

题意

在一张有向图中,有一个起点和一个终点,你需要删去部分路径,使得起点到终点的最短距离增加(并不要求需要使得距离变成最大值),且删除的路径长度最短。求删去的路径总长为多少

分析

一开始理解错题意了,以为是在保证路径变成最长的路径之后,求删去的路径和最小是多少。然后就自闭了很久,还WA了好几发。后来看到题目中是 longer 而不是 longest 。突然醒悟。直接最短路径 +网络流就行,中间重新建图。

大致的过程是先跑最短路径(我用了SPFA算法,因为当数据量较大时,图为稀疏图,所以用邻接表形式),然后求出起点到每一个点的距离(保存在数组 dist 中)。然后删掉所有的边,对满足下面等式的边进行重建(网络流的边,即同时需要搭建反向的边,只不过流量为0),然后跑网络流(我用了ISAP算法,仍然是邻接表)

dist[a]−dist[b]=edge[atob]dist[a] - dist[b] = edge[a to b]dist[a]−dist[b]=edge[atob]

atoba to batob 指代这条边起点为 aaa 终点为 bbb,且满足 edge[btoa]=−edge[atob]edge[b to a] = - edge[a to b]edge[btoa]=−edge[atob]

AC代码

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. #define MAXN 20100
  4. #define MAXM 20100
  5. bool visited[MAXN]; //标记数组
  6. long long dist[MAXN]; //源点到顶点i的最短距离
  7. long long path[MAXN]; //记录最短路的路径
  8. long long enqueue_num[MAXN]; //记录入队次数
  9. long long vertex_num; //顶点数
  10. long long edge_num; //边数
  11. long long source; //源点
  12. struct Edge
  13. {
  14. long long to, next, cap, flow;
  15. } edge[MAXM];
  16. long long head[MAXN];
  17. long long tot;
  18. long long gap[MAXN], dep[MAXN], cur[MAXN];
  19. void init()
  20. {
  21. tot = 0;
  22. memset(head, -1, sizeof(head));
  23. }
  24. void addedge(long long u, long long v, long long w)
  25. {
  26. edge[tot].to = v;
  27. edge[tot].cap = w;
  28. edge[tot].next = head[u];
  29. edge[tot].flow = 0;
  30. head[u] = tot++;
  31. }
  32. bool SPFA()
  33. {
  34. memset(visited, 0, sizeof(visited));
  35. memset(enqueue_num, 0, sizeof(enqueue_num));
  36. for (long long i = 0; i < vertex_num; i++)
  37. {
  38. dist[i] = __LONG_LONG_MAX__;
  39. path[i] = source;
  40. }
  41. queue<long long> Q;
  42. Q.push(source);
  43. dist[source] = 0;
  44. visited[source] = true;
  45. enqueue_num[source]++;
  46. while (!Q.empty())
  47. {
  48. long long u = Q.front();
  49. Q.pop();
  50. visited[u] = 0;
  51. for (long long curnode = head[u]; curnode != -1; curnode = edge[curnode].next)
  52. {
  53. if (dist[u] + edge[curnode].cap < dist[edge[curnode].to])
  54. {
  55. dist[edge[curnode].to] = dist[u] + edge[curnode].cap;
  56. path[edge[curnode].to] = u;
  57. if (!visited[edge[curnode].to])
  58. {
  59. Q.push(edge[curnode].to);
  60. enqueue_num[edge[curnode].to]++;
  61. if (enqueue_num[edge[curnode].to] >= vertex_num)
  62. return false;
  63. visited[edge[curnode].to] = 1;
  64. }
  65. }
  66. }
  67. }
  68. return true;
  69. }
  70. long long Q[MAXN];
  71. void BFS(long long start, long long end)
  72. {
  73. memset(dep, -1, sizeof(dep));
  74. memset(gap, 0, sizeof(gap));
  75. gap[0] = 1;
  76. long long front = 0, rear = 0;
  77. dep[end] = 0;
  78. Q[rear++] = end;
  79. while (front != rear)
  80. {
  81. long long u = Q[front++];
  82. for (long long i = head[u]; i != -1; i = edge[i].next)
  83. {
  84. long long v = edge[i].to;
  85. if (dep[v] != -1)
  86. continue;
  87. Q[rear++] = v;
  88. dep[v] = dep[u] + 1;
  89. gap[dep[v]]++;
  90. }
  91. }
  92. }
  93. long long S[MAXN];
  94. long long sap(long long start, long long end, long long N)
  95. {
  96. BFS(start, end);
  97. memcpy(cur, head, sizeof(head));
  98. long long top = 0;
  99. long long u = start;
  100. long long ans = 0;
  101. while (dep[start] < N)
  102. {
  103. if (u == end)
  104. {
  105. long long Min = __LONG_LONG_MAX__;
  106. long long inser;
  107. for (long long i = 0; i < top; i++)
  108. {
  109. if (Min > edge[S[i]].cap - edge[S[i]].flow)
  110. {
  111. Min = edge[S[i]].cap - edge[S[i]].flow;
  112. inser = i;
  113. }
  114. }
  115. for (long long i = 0; i < top; i++)
  116. {
  117. edge[S[i]].flow += Min;
  118. edge[S[i] ^ 1].flow -= Min;
  119. }
  120. ans += Min;
  121. top = inser;
  122. u = edge[S[top] ^ 1].to;
  123. continue;
  124. }
  125. bool flag = false;
  126. long long v;
  127. for (long long i = cur[u]; i != -1; i = edge[i].next)
  128. {
  129. v = edge[i].to;
  130. if (edge[i].cap - edge[i].flow && dep[v] + 1 == dep[u])
  131. {
  132. flag = true;
  133. cur[u] = i;
  134. break;
  135. }
  136. }
  137. if (flag)
  138. {
  139. S[top++] = cur[u];
  140. u = v;
  141. continue;
  142. }
  143. long long Min = N;
  144. for (long long i = head[u]; i != -1; i = edge[i].next)
  145. if (edge[i].cap - edge[i].flow && dep[edge[i].to] < Min)
  146. {
  147. Min = dep[edge[i].to];
  148. cur[u] = i;
  149. }
  150. gap[dep[u]]--;
  151. if (!gap[dep[u]])
  152. return ans;
  153. dep[u] = Min + 1;
  154. gap[dep[u]]++;
  155. if (u != start)
  156. u = edge[S[--top] ^ 1].to;
  157. }
  158. return ans;
  159. }
  160. long long n, m;
  161. int a[MAXN], b[MAXN], c[MAXN];
  162. void reISAP()
  163. {
  164. init();
  165. for (int i = 0; i < m; i++)
  166. {
  167. if (c[i] == dist[b[i]] - dist[a[i]])
  168. {
  169. addedge(a[i], b[i], c[i]);
  170. addedge(b[i], a[i], 0);
  171. }
  172. }
  173. }
  174. int main()
  175. {
  176. #ifdef ACM_LOCAL
  177. freopen("./in.txt", "r", stdin);
  178. freopen("./out.txt", "w", stdout);
  179. #endif
  180. ios::sync_with_stdio(false);
  181. long long t;
  182. cin >> t;
  183. while (t--)
  184. {
  185. cin >> n >> m;
  186. source = 1;
  187. vertex_num = n + 1;
  188. init();
  189. for (long long i = 0; i < m; i++)
  190. {
  191. cin >> a[i] >> b[i] >> c[i];
  192. addedge(a[i], b[i], c[i]);
  193. }
  194. if (!SPFA())
  195. {
  196. cout << '0' << endl;
  197. continue;
  198. }
  199. reISAP();
  200. cout << sap(1, n, n) << endl;
  201. }
  202. return 0;
  203. }

总结

理解了题意之后感觉就是一道板子题……

人尽皆知**题

【2019多校第一场补题 / HDU6582】2019多校第一场E题1005Path——最短路径+网络流的更多相关文章

  1. NOI.AC NOIP模拟赛 第一场 补记

    NOI.AC NOIP模拟赛 第一场 补记 candy 题目大意: 有两个超市,每个超市有\(n(n\le10^5)\)个糖,每个糖\(W\)元.每颗糖有一个愉悦度,其中,第一家商店中的第\(i\)颗 ...

  2. NOI.AC NOIP模拟赛 第四场 补记

    NOI.AC NOIP模拟赛 第四场 补记 子图 题目大意: 一张\(n(n\le5\times10^5)\)个点,\(m(m\le5\times10^5)\)条边的无向图.删去第\(i\)条边需要\ ...

  3. 2019年第一天——使用Visual Studio 2019 Preview创建第一个ASP.Net Core3.0的App

    一.前言: 全文翻译自:https://www.talkingdotnet.com/creating-first-asp-net-core-3-0-app-visual-studio-2019/ Vi ...

  4. 计蒜客 NOIP 提高组模拟竞赛第一试 补记

    计蒜客 NOIP 提高组模拟竞赛第一试 补记 A. 广场车神 题目大意: 一个\(n\times m(n,m\le2000)\)的网格,初始时位于左下角的\((1,1)\)处,终点在右上角的\((n, ...

  5. NOI.AC NOIP模拟赛 第二场 补记

    NOI.AC NOIP模拟赛 第二场 补记 palindrome 题目大意: 同[CEOI2017]Palindromic Partitions string 同[TC11326]Impossible ...

  6. NOI.AC NOIP模拟赛 第三场 补记

    NOI.AC NOIP模拟赛 第三场 补记 列队 题目大意: 给定一个\(n\times m(n,m\le1000)\)的矩阵,每个格子上有一个数\(w_{i,j}\).保证\(w_{i,j}\)互不 ...

  7. 剑指offer35题:第一个只出现一次的字符+剑指offer55题:字符流中第一个不重复的字符+剑指offer51题:数组中重复的数字

    在看剑指offer的时候,感觉这三个题目很像,都是用哈希表可以解决,所以把这三个题整理出来,以供复习. 剑指offer35题:第一个只出现一次的字符 题目描述:在字符串中找出第一个只出现一次的字符.如 ...

  8. Azure DevOps Server 2019 第一个补丁包(2019.0.1 RTW)

    在Azure DevOps Server 2019正式发布后的2周左右时间,微软快速发布了第一个补丁包Azure DevOps Server 2019.0.1 RTW.Azure DevOps Ser ...

  9. SQL SERVER 2005中如何获取日期(一个月的最后一日、上个月第一天、最后一天、一年的第一日等等)

    原文:[转]SQL SERVER 2005中如何获取日期(一个月的最后一日.上个月第一天.最后一天.一年的第一日等等) 在网上找到的一篇文章,相当不错哦O(∩_∩)O~ //C#本周第一天       ...

随机推荐

  1. 深入理解Tomcat(12)拾遗

    前言 如何使用? 源码解读 总结 前言 Tomcat为了提高性能,在接受到socket传入的字节之后并不会马上进行编码转换,而是保持byte[]的方式,在用到的时候再进行转换.在tomcat的实现中, ...

  2. 《HelloGitHub》第 47 期

    兴趣是最好的老师,HelloGitHub 就是帮你找到兴趣! 简介 分享 GitHub 上有趣.入门级的开源项目. 这是一个面向编程新手.热爱编程.对开源社区感兴趣 人群的月刊,月刊的内容包括:各种编 ...

  3. NumPy的随机函数子库——numpy.random

    NumPy的随机函数子库numpy.random 导入模块:import numpy as np 1.numpy.random.rand(d0,d1,...,dn) 生成一个shape为(d0,d1, ...

  4. Scrum 敏捷实践中的三大角色

    在我过去的近两年工作中,我们一直在应用 Scrum 敏捷项目管理方法来开展工作,今天,我先从它的角色划分来讲起,毕竟这可是它最鲜明的特征. 首先,为什么这种项目管理方法叫 Scrum ? Scrum ...

  5. Web中间件常见漏洞总结

    一.IIS中间组件: 1.PUT漏洞 2.短文件名猜解 3.远程代码执行 4.解析漏洞 二.Apache中间组件: 1.解析漏洞 2.目录遍历 三.Nginx中间组件: 1.文件解析 2.目录遍历 3 ...

  6. 7-35 jmu-python-求三角形面积及周长 (10 分)

    输入的三角形的三条边a.b.c,计算并输出面积和周长.假设输入三角形三边是合法整形数据. 三角形面积计算公式:  ,其中s=(a+b+c)/2. import math #导入math库 math.s ...

  7. 原型模式故事链(3)--JS的数据类型、以及区别、区分、转化

    上一章--原型链讲解:传送门:https://segmentfault.com/a/11... 在上一章讲解原型链时提到了:所有的引用类型都有一个_proto_属性,称之为隐式原型.那么引用类型是什么 ...

  8. HTML常用表单标签

    1.表单元素 <form> HTML 表单用于收集用户输入. 代码示例: <form action="http://xxx.xxx.xxx/xxx.php" me ...

  9. SAP CRM Transaction处理中的权限控制

    当试图打开一个Opportunity时, 系统会进行如下一系列的权限检查: 1. 检查Authorization object CRM_ORD_OP: 此处会检查当前user的partner func ...

  10. vue中的插槽(slot)

    vue中的插槽,指的是子组件中提供给父组件使用的一个占位符,用<slot></slot>标签表示,父组件可以在这个占位符中填充任何模板代码,比如HTML.组件等,填充的内容会替 ...