题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6582

题意:删掉边使得1到n的最短路改变,删掉边的代价为该边的边权。求最小代价。

比赛时一片浆糊,赛后听到dinic瞬间思维通透XD

大致做法就是先跑一遍最短路,然后再保留所有满足dis[i]+w==dis[j]的边,在这些边上跑最小割(dinic)。

代码写的异常丑陋,见谅QAQ

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstdlib>
  4. #include<algorithm>
  5. #include<cstring>
  6. #include<string>
  7. #include<queue>
  8. using namespace std;
  9. typedef long long ll;
  10. const ll maxn = 3e5 + ;
  11. const ll inf = 1e18;
  12. struct node {
  13. ll s, e, next;
  14. ll w;
  15. }edge[maxn * ], edge2[maxn * ];
  16. ll head[maxn], head2[maxn], len, len2;
  17. void init() {
  18. memset(head, -, sizeof(head));
  19. memset(head2, -, sizeof(head2));
  20. len = len2 = ;
  21. }
  22. void add(ll s, ll e, ll w) {
  23. edge[len].s = s;
  24. edge[len].e = e;
  25. edge[len].w = w;
  26. edge[len].next = head[s];
  27. head[s] = len++;
  28. }
  29. void add2(ll s, ll e, ll w) {
  30. edge2[len2].s = s;
  31. edge2[len2].e = e;
  32. edge2[len2].w = w;
  33. edge2[len2].next = head2[s];
  34. head2[s] = len2++;
  35. }
  36. struct p {
  37. ll dis, num;
  38. bool operator<(const p&a)const {
  39. return a.dis < dis;
  40. }
  41. };
  42. ll dis[maxn];
  43. ll vis[maxn];
  44. void dij(ll n) {
  45. priority_queue<p>q;
  46. for (ll i = ; i <= n; i++)
  47. dis[i] = inf, vis[i] = ;
  48. q.push({ 0ll,1ll });
  49. dis[] = 0ll;
  50. while (!q.empty()) {
  51. ll x = q.top().num;
  52. q.pop();
  53. if (vis[x])
  54. continue;
  55. vis[x] = ;
  56. for (ll i = head[x]; i != -; i = edge[i].next) {
  57. ll y = edge[i].e;
  58. if (dis[y] > dis[x] + edge[i].w) {
  59. dis[y] = dis[x] + edge[i].w;
  60. q.push({ dis[y],y });
  61. }
  62. }
  63. }
  64. }
  65. ll d[maxn];
  66. bool bfs(ll s, ll t) {
  67. queue<ll>q;
  68. memset(d, , sizeof(d));
  69. d[s] = 1ll;
  70. q.push(s);
  71. while (!q.empty()) {
  72. ll x = q.front(); q.pop();
  73. for (ll i = head2[x]; i != -; i = edge2[i].next) {
  74. ll y = edge2[i].e;
  75. if (edge2[i].w && !d[y]) {
  76. d[y] = d[x] + 1ll;
  77. q.push(y);
  78. }
  79. }
  80. }
  81. return d[t];
  82. }
  83. ll dfs(ll x, ll t, ll limit) {
  84. if (x == t)
  85. return limit;
  86. ll add, ans = ;
  87. for (ll i = head2[x]; i != -; i = edge2[i].next) {
  88. ll y = edge2[i].e;
  89. if (d[y] == d[x] + && edge2[i].w) {
  90. add = dfs(y, t, min(limit, edge2[i].w));
  91. edge2[i].w -= add;
  92. edge2[i ^ ].w += add;
  93. ans += add;
  94. limit -= add;
  95. if (!limit)
  96. break;
  97. }
  98. }
  99. if (!ans)
  100. d[x] = -;
  101. return ans;
  102. }
  103. ll dinic(ll s, ll t) {
  104. ll ans = ;
  105. while (bfs(s, t))
  106. ans += dfs(s, t, inf);
  107. return ans;
  108. }
  109. int main() {
  110. ll t;
  111. scanf("%lld", &t);
  112. while (t--) {
  113. ll n, m;
  114. init();
  115. scanf("%lld%lld", &n, &m);
  116. ll x, y, z;
  117. for (ll i = ; i <= m; i++) {
  118. scanf("%lld%lld%lld", &x, &y, &z);
  119. add(x, y, z);
  120. }
  121. dij(n);
  122. for (ll i = ; i <= n; i++)
  123. for (ll j = head[i]; j != -; j = edge[j].next)
  124. if (dis[edge[j].s] + edge[j].w == dis[edge[j].e])
  125. add2(edge[j].s, edge[j].e, edge[j].w), add2(edge[j].e, edge[j].s, 0ll);
  126. printf("%lld\n", dinic(, n));
  127. }
  128. return ;
  129. }

[2019杭电多校第一场][hdu6582]Path(最短路&&最小割)的更多相关文章

  1. 2019杭电多校第一场hdu6581 Vacation

    Vacation 题目传送门 update(O(n)) 看了那个O(n)的方法,感觉自己想的那个O(nlogn)的好傻,awsl. 0车最终通过停车线的时候,状态一定是某个车堵住后面的所有车(这个车也 ...

  2. [2019杭电多校第一场][hdu6583]Typewriter(后缀自动机&&dp)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6583 大致题意是说可以花费p在字符串后添加一个任意字符,或者花费q在字符串后添加一个当前字符串的子串. ...

  3. [2019杭电多校第一场][hdu6579]Operation(线性基)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6579 题目大意是两个操作,1个是求[l,r]区间子序列的最大异或和,另一个是在最后面添加一个数. 如果 ...

  4. [2019杭电多校第一场][hdu6578]Blank(dp)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6578 计数问题想到dp不过分吧... dp[i][j][k][w]为第1-i位置中4个数最后一次出现的 ...

  5. 2019杭电多校第一场hdu6579 Operation(线性基)

    Operation 题目传送门 解题思路 把右边的数尽量往高位放,构造线性基的时候同时记录其在原序列中的位置,在可以插入的时候如果那个位置上存在的数字的位置比新放入的要小,就把旧的往后挤.用这种发现构 ...

  6. 2018 Multi-University Training Contest 1 杭电多校第一场

    抱着可能杭电的多校1比牛客的多校1更恐怖的想法 看到三道签到题 幸福的都快哭出来了好吗 1001  Maximum Multiple(hdoj 6298) 链接:http://acm.hdu.edu. ...

  7. 2019年杭电多校第一场 1009题String(HDU6586+模拟+单调栈)

    题目链接 传送门 题意 给你一个字符串,要你构造一个长为\(k\)的子串使得每个字母出现的次数在\([L_i,R_i](0\leq i\leq26)\)间且字典序最小. 思路 做这种题目就是要保持思路 ...

  8. 2019年杭电多校第一场 1004题Vacation(HDU6581+数学)

    题目链接 传送门 题意 有\(n+1\)辆车要过红绿灯,告诉你车的长度.与红绿灯的起点(题目假设红绿灯始终为绿).车的最大速度,问你第\(0\)辆车(距离最远)车头到达红绿灯起点的时间是多少(每辆车最 ...

  9. 2019年杭电多校第一场 1002题Operation(HDU6579+线性基)

    题目链接 传送门 题意 初始时有\(n\)个数,现在有\(q\)次操作: 查询\([l,r]\)内选择一些数使得异或和最大: 在末尾加入一个数. 题目强制在线. 思路 对于\(i\)我们记录\([1, ...

随机推荐

  1. C++练习 | 文件流应用(1)

    #include <iostream> #include <cmath> #include <cstring> #include <string> #i ...

  2. leecode刷题(27)-- 合并k个排序链表

    leecode刷题(27)-- 合并k个排序链表 合并k个排序链表 合并 k 个排序链表,返回合并后的排序链表.请分析和描述算法的复杂度. 示例: 输入: [ 1->4->5, 1-> ...

  3. Clang教程之实现源源变化

    clang教程之实现源源变化 声明:本教程来自于Eli Bendersky's website 原文地址:http://eli.thegreenplace.net/2014/05/01/modern- ...

  4. HttpClient 释放连接

    Release the Connection:释放连接 This is a crucial step to keep things flowing. We must tell HttpClient t ...

  5. 用ant打包

    Eclipse 内置了 Ant . Ant 是一种类似于批处理程序的软件包,它主要繁琐的工作是编写和调试自动处理脚本(一个 XML 文件),但只要有了这个脚本,我们就可以一键完成所有的设定工作. 本节 ...

  6. Shell脚本之sed详解

    在编写shell脚本的过程中,我们经常需要使用sed流编辑器和awk对文本文件进行处理. 一.什么是sed? sed 是一种在线编辑器,它一次处理一行内容.sed是非交互式的编辑器.它不会修改文件,除 ...

  7. Logback日志输出到ELK

    用docker-compose本机部署elk docker-compose.yml version: "3" services: es01: image: docker.elast ...

  8. 001-CentOS 7系统搭建Rsyslog+LogAnalyzer解决交换机日志收

    日志功能对于操作系统是相当重要的,在使用中,无论是系统还是应用等等,出了任何问题,我们首先想到的便是分析日志,查找问题原因.自 CentOS 7 开始,我们的 CentOS 便开始使用 rsyslog ...

  9. 使用putty对linux与windows之间的文件传输

    一.putty下载 首先下载pytty,解压开发现里面有plink.exe pscp.exe psftp.exe putty.exe puttygen.exe puttytel.exe等可执行文件 进 ...

  10. Linux排查问题工具汇总

    geektime专栏<linux性能优化实战>笔记 一.Linux问题排查命令 uptime top free vmstat iostat ifstat 二.Sun JDK自带工具 jps ...