题意

链接:https://vjudge.net/problem/HDU-6582

给定一个有向图,可以有重边,每条边上有一个权值表示删掉这条边的代价,问最少花费多少代价能使从s到t节点的最短路径增大?1≤n,m≤10000

思路

容易想到应该是删最短路上的边,最短路可能不止一条,所以使原图1到n的所有最短路不连通即可,这就是最小割呀!选出权值和最小的边使得图不连通,这里是使最短路图不连通。

所以做法就是先建两个图,一个是u->v的有向边,另一个是v->u的有向边,从1跑一下Dijkstra,从n跑一下Dijkstra,我们枚举每条边(u,v),如果这条边是最短路上的边,那么应满足dis1[u]+val(u,v)+dis2[v]=dis1[n],即1到u的最短距离+u到v的距离+v到n的最短距离=1到n的最短距离。

最小割=最大流,跑一下Dinic即可啦。

代码

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define ll long long
  4. #define int ll
  5. const int N=1e6+5;
  6. const ll inf=1e16;
  7. struct node
  8. {
  9. int p,w;
  10. node(int a,int b)
  11. {
  12. p=a;
  13. w=b;
  14. }
  15. friend bool operator<(node a,node b) //权值小的先出队
  16. {
  17. if(a.w!=b.w) return a.w>b.w;
  18. return a.p>b.p;
  19. }
  20. };
  21. vector <node> eg1[N],eg2[N];
  22. int dis1[N],n,dis2[N];
  23. void add1(int u,int v,int w)
  24. {
  25. eg1[u].push_back(node(v,w));
  26. }
  27. void add2(int u,int v,int w)
  28. {
  29. eg2[u].push_back(node(v,w));
  30. }
  31. void Dijkstra1(int now)
  32. {
  33. for(int i=0; i<=n; i++) dis1[i]=inf;
  34. dis1[now]=0;
  35. priority_queue <node> pq;
  36. pq.push(node(now,dis1[now]));
  37. while(!pq.empty())
  38. {
  39. node f=pq.top();
  40. pq.pop();
  41. for(int i=0; i<eg1[f.p].size(); i++)
  42. {
  43. node t=eg1[f.p][i];
  44. if(dis1[t.p]>t.w+f.w)
  45. {
  46. dis1[t.p]=t.w+f.w;
  47. pq.push(node(t.p,dis1[t.p]));
  48. }
  49. }
  50. }
  51. }
  52. void Dijkstra2(int now)
  53. {
  54. for(int i=0; i<=n; i++) dis2[i]=inf;
  55. dis2[now]=0;
  56. priority_queue <node> pq;
  57. pq.push(node(now,dis2[now]));
  58. while(!pq.empty())
  59. {
  60. node f=pq.top();
  61. pq.pop();
  62. for(int i=0; i<eg2[f.p].size(); i++)
  63. {
  64. node t=eg2[f.p][i];
  65. if(dis2[t.p]>t.w+f.w)
  66. {
  67. dis2[t.p]=t.w+f.w;
  68. pq.push(node(t.p,dis2[t.p]));
  69. }
  70. }
  71. }
  72. }
  73. /***************************************/
  74. int x,y,z,maxflow,deep[N];//deep深度
  75. struct Edge
  76. {
  77. int next,to,dis;
  78. } edge[N];
  79. int num_edge=-1,head[N],cur[N];//cur用于复制head
  80. queue <int> q;
  81. void add_edge(int from,int to,int dis,bool flag)
  82. {
  83. edge[++num_edge].next=head[from];
  84. edge[num_edge].to=to;
  85. if (flag) edge[num_edge].dis=dis;//反图的边权为 0
  86. head[from]=num_edge;
  87. }
  88. //bfs用来分层
  89. bool bfs(int s,int t)
  90. {
  91. memset(deep,0x7f,sizeof(deep));
  92. while (!q.empty()) q.pop();
  93. for (int i=1; i<=n; i++) cur[i]=head[i];
  94. deep[s]=0;
  95. q.push(s);
  96. while (!q.empty())
  97. {
  98. int now=q.front();
  99. q.pop();
  100. for (int i=head[now]; i!=-1; i=edge[i].next)
  101. {
  102. if (deep[edge[i].to]>inf && edge[i].dis)//dis在此处用来做标记 是正图还是返图
  103. {
  104. deep[edge[i].to]=deep[now]+1;
  105. q.push(edge[i].to);
  106. }
  107. }
  108. }
  109. if (deep[t]<inf) return true;
  110. else return false;
  111. }
  112. //dfs找增加的流的量
  113. int dfs(int now,int t,int limit)//limit为源点到这个点的路径上的最小边权
  114. {
  115. if (!limit || now==t) return limit;
  116. int flow=0,f;
  117. for (int i=cur[now]; i!=-1; i=edge[i].next)
  118. {
  119. cur[now]=i;
  120. if (deep[edge[i].to]==deep[now]+1 && (f=dfs(edge[i].to,t,min(limit,edge[i].dis))))
  121. {
  122. flow+=f;
  123. limit-=f;
  124. edge[i].dis-=f;
  125. edge[i^1].dis+=f;
  126. if (!limit) break;
  127. }
  128. }
  129. return flow;
  130. }
  131. void Dinic(int s,int t)
  132. {
  133. while (bfs(s,t))
  134. maxflow+=dfs(s,t,inf);
  135. }
  136. /***********************************************/
  137. signed main()
  138. {
  139. int u,v,m,w,t;
  140. scanf("%lld",&t);
  141. while(t--)
  142. {
  143. scanf("%lld%lld",&n,&m);
  144. for(int i=0; i<=n; i++) eg1[i].clear(),eg2[i].clear();
  145. for(int i=0; i<m; i++)
  146. {
  147. scanf("%lld%lld%lld",&u,&v,&w);
  148. add1(u,v,w);
  149. add2(v,u,w);
  150. }
  151. Dijkstra1(1);
  152. Dijkstra2(n);
  153. memset(head,-1,sizeof(head));
  154. for(int i=1; i<=n; i++)
  155. {
  156. int sz=eg1[i].size();
  157. for(int j=0; j<sz; j++)
  158. {
  159. if(dis1[i]+eg1[i][j].w+dis2[eg1[i][j].p]==dis1[n])
  160. {
  161. add_edge(i,eg1[i][j].p,eg1[i][j].w,1);
  162. add_edge(eg1[i][j].p,i,eg1[i][j].w,0);
  163. }
  164. }
  165. }
  166. maxflow=0;
  167. Dinic(1,n);
  168. printf("%lld\n",maxflow);
  169. }
  170. return 0;
  171. }

2019 Multi-University Training Contest 1 E Path(最短路+最小割)的更多相关文章

  1. 2019 Multi-University Training Contest 1 Path(最短路+最小割)

    题意:给你n个点 m条边 现在你能够堵住一些路 问怎样能让花费最少且让1~n走的路比最短路的长度要长 思路:先跑一边最短路 建一个最短路图 然后我们跑一边最大流求一下最小割即可 #include &l ...

  2. [2019杭电多校第一场][hdu6582]Path(最短路&&最小割)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6582 题意:删掉边使得1到n的最短路改变,删掉边的代价为该边的边权.求最小代价. 比赛时一片浆糊,赛后 ...

  3. 2019HDU多校Path——最短路最小割

    题目 给出一个 $n$ 个顶点 $m$ 条边的图,要求阻塞一些边,使得从 $1$ 到 $n$ 的最短路变长,求阻塞的边长度和的最小值,不必保证阻塞后可达. 分析 很显然,要阻塞的边肯定在最短路图上,先 ...

  4. HDU - 6582 Path (最短路+最小割)

    题意:给定一个n个点m条边的有向图,每条边有个长度,可以花费等同于其长度的代价将其破坏掉,求最小的花费使得从1到n的最短路变长. 解法:先用dijkstra求出以1为源点的最短路,并建立最短路图(只保 ...

  5. 2019 Nowcoder Multi-University Training Contest 4 E Explorer

    线段树分治. 把size看成时间,相当于时间 $l$ 加入这条边,时间 $r+1$ 删除这条边. 注意把左右端点的关系. #include <bits/stdc++.h> ; int X[ ...

  6. 2019 Nowcoder Multi-University Training Contest 1 H-XOR

    由于每个元素贡献是线性的,那么等价于求每个元素出现在多少个异或和为$0$的子集内.因为是任意元素可以去异或,那么自然想到线性基.先对整个集合A求一遍线性基,设为$R$,假设$R$中元素个数为$r$,那 ...

  7. [2019杭电多校第二场][hdu6598]Harmonious Army(最小割)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6598 题意是说一个军队有n人,你可以给他们每个人安排战士或者法师的职业,有m对人有组合技,组合技的信息 ...

  8. [最短路,最大流最小割定理] 2019 Multi-University Training Contest 1 Path

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=6582 Path Time Limit: 2000/1000 MS (Java/Others)    Mem ...

  9. 2019 Multi-University Training Contest 1

    2019 Multi-University Training Contest 1 A. Blank upsolved by F0_0H 题意 给序列染色,使得 \([l_i,r_i]\) 区间内恰出现 ...

随机推荐

  1. Spring Boot 2 构建可部署的war包

    默认情况下Spring Boot使用了内嵌的Tomcat服务器,项目最终被打成jar包运行,每个jar包可以被看作一个独立的Web服务器.传统的Web开发,一般会将Web应用打成一个war包,然后将其 ...

  2. EChart绘制风速风向曲线分析图

    1.获取ECharts 在 ECharts 的 GitHub 上下载最新的 release 版本,解压出来的文件夹里的 dist 目录里可以找到最新版本的 echarts 库. 2.引入ECharts ...

  3. Error 942 occured during Initialization of Bufq KUPC$S_1_20181023155636

      一台ORACLE实例(Oracle Database 10g Release 10.2.0.5.0)启动时,报"Error 942 occured during Initializati ...

  4. MySQL问题记录——2003-Can't connect to MySQL server on 'localhost'(10038)

    MySQL问题记录——2003-Can't connect to MySQL server on 'localhost'(10038) 摘要:本文主要记录了连接到MySQL数据库时出现的问题以及解决办 ...

  5. 【转载】XSS攻击和sql注入

    XSS攻击: https://www.cnblogs.com/dolphinX/p/3391351.html 跨站脚本攻击(Cross Site Script为了区别于CSS简称为XSS)指的是恶意攻 ...

  6. FormData的介绍(一)

    FormData对象介绍FormData字母意思是表单数据,H5新增的一个内置对象.可以获取任何类型的表单数据,如text radio checkbox file textarea 常用语发送ajax ...

  7. 三、ITK的dcm图像读写

    一.主要功能 1.读取单张dcm图像 2.写入单张dcm图像 3.图像调整之后以.jpg格式写入 4.调整之后重新以.dcm格式写入 二.代码 #include "itkImageFileR ...

  8. git 代码管理

  9. matlab练习程序(点云密度)

    算法思路是首先建立kd树,然后找到每个点距离最近的点的距离,对距离求和再求平均即可. 代码如下: clear all; close all; clc; pc = pcread('rabbit.pcd' ...

  10. .NET Core 序列化对象输出字节数大小比较

    写代码验证了一下 .NET Core 中序列化对象输出字节数大小,.NET Core 版本是 3.0.100-preview8-013656 ,对象属性使用了 Guid 与 DateTime 类型,胜 ...