对于最小费用最大流,我们的通常做法是EK+SPFA。

然而,卡常界大佬ZKW发明了一个求解最小费用最大流的方法,很强啊。

在学ZKW费用流前,先说说KM算法。

KM算法

为啥要先提这个呢?因为ZKW费用流用了一个和它非常类似的做法。

KM算法求的是二分图最大权完美匹配。

在此,我来口胡一下(这个算法其实我并未打过,只懂思想)。

和匈牙利算法差不多,区别在于标号。

对于左右两边的点各自有个标号D" role="presentation">DD,一开始,左边的标号设为最大的连出去的边的权值,右边的设为0。

每次只走,满足Di+Dj=v" role="presentation">Di+Dj=vDi+Dj=v的边。

当发生冲突时,就将右边的点的标号全部加一,左边的点的标号全部减一,然后继续搞。

这就是KM算法的大概思路。

ZKW费用流

到正题了。

类似于KM算法,ZKW算法也有个标号。

当Dx=Dy+w" role="presentation">Dx=Dy+wDx=Dy+w时,才会走这条边。

ZKW算法中,是类似于Dinic的多路增广,在每次增广后,就修改距离标号。

求出距离标号的最小增加值,然后修改距离标号。

当找不出增广路时,算法结束。

代码

  1. using namespace std;
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <algorithm>
  5. #include <climits>
  6. int n,m,S,T;
  7. struct EDGE
  8. {
  9. int to,c,w;
  10. EDGE *las;
  11. } e[100001];
  12. int ne;
  13. EDGE *last[5001];
  14. #define rev(ei) (e+(int((ei)-e)^1))
  15. int maxflow,mincost;
  16. bool vis[5001];
  17. int dis[5001];
  18. int dfs(int,int);
  19. bool change();
  20. void flow();
  21. int main()
  22. {
  23. scanf("%d%d%d%d",&n,&m,&S,&T);
  24. for (int i=1;i<=m;++i)
  25. {
  26. int u,v,c,w;
  27. scanf("%d%d%d%d",&u,&v,&c,&w);
  28. e[ne]={v,c,w,last[u]};
  29. last[u]=e+ne;
  30. ++ne;
  31. e[ne]={u,0,-w,last[v]};
  32. last[v]=e+ne;
  33. ++ne;
  34. }
  35. flow();
  36. printf("%d %d\n",maxflow,mincost);
  37. return 0;
  38. }
  39. int dfs(int x,int s)
  40. {
  41. if (x==T)
  42. {
  43. maxflow+=s;
  44. mincost+=dis[S]*s;
  45. return s;
  46. }
  47. vis[x]=1;
  48. int have=0;
  49. for (EDGE *ei=last[x];ei;ei=ei->las)
  50. if (!vis[ei->to] && ei->c && dis[ei->to]+ei->w==dis[x])
  51. {
  52. int t=dfs(ei->to,min(s-have,ei->c));
  53. ei->c-=t;
  54. rev(ei)->c+=t;
  55. have+=t;
  56. }
  57. return have;
  58. }
  59. bool change()
  60. {
  61. int d=INT_MAX;
  62. for (int i=1;i<=n;++i)
  63. if (vis[i])
  64. for (EDGE *ei=last[i];ei;ei=ei->las)
  65. if (!vis[ei->to] && ei->c)
  66. d=min(d,dis[ei->to]-dis[i]+ei->w);//找出最小增加值
  67. if (d==INT_MAX)
  68. return 0;
  69. for (int i=1;i<=n;++i)
  70. if (vis[i])
  71. dis[i]+=d;//更改距离标号
  72. return 1;
  73. }
  74. void flow()
  75. {
  76. maxflow=0;
  77. mincost=0;
  78. do
  79. do
  80. memset(vis,0,sizeof vis);
  81. while (dfs(S,INT_MAX));
  82. while (change());
  83. }

最小费用最大流——ZKW的更多相关文章

  1. 洛谷.3381.[模板]最小费用最大流(zkw)

    题目链接 Update:我好像刚知道多路增广就是zkw费用流.. //1314ms 2.66MB 本题优化明显 #include <queue> #include <cstdio&g ...

  2. 【BZOJ-3876】支线剧情 有上下界的网络流(有下界有源有汇最小费用最大流)

    3876: [Ahoi2014]支线剧情 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 821  Solved: 502[Submit][Status ...

  3. BZOJ-1061 志愿者招募 线性规划转最小费用最大流+数学模型 建模

    本来一眼建模,以为傻逼题,然后发现自己傻逼...根本没想到神奇的数学模型..... 1061: [Noi2008]志愿者招募 Time Limit: 20 Sec Memory Limit: 162 ...

  4. BZOJ-1070 修车 最小费用最大流+拆点+略坑建图

    1070: [SCOI2007]修车 Time Limit: 1 Sec Memory Limit: 162 MB Submit: 3624 Solved: 1452 [Submit][Status] ...

  5. 【BZOJ】1221: [HNOI2001] 软件开发(最小费用最大流)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1221 先吐槽一下,数组依旧开小了RE:在spfa中用了memset和<queue>的版本 ...

  6. bzoj 1927 [Sdoi2010]星际竞速(最小费用最大流)

    1927: [Sdoi2010]星际竞速 Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 1576  Solved: 954[Submit][Statu ...

  7. Luogu P3381 (模板题) 最小费用最大流

    <题目链接> 题目大意: 给定一张图,给定条边的容量和单位流量费用,并且给定源点和汇点.问你从源点到汇点的最带流和在流量最大的情况下的最小费用. 解题分析: 最小费用最大流果题. 下面的是 ...

  8. POJ - 2516 Minimum Cost(最小费用最大流)

    1.K种物品,M个供应商,N个收购商.每种物品从一个供应商运送到一个收购商有一个单位运费.每个收购商都需要K种物品中的若干.求满足所有收购商需求的前提下的最小运费. 2.K种物品拆开来,分别对每种物品 ...

  9. LOJ#3097 [SNOI2019]通信 最小费用最大流+cdq分治/主席树/分块优化建图

    瞎扯 我们网络流模拟赛(其实是数据结构模拟赛)的T2. 考场上写主席树写自闭了,直接交了\(80pts\)的暴力,考完出来突然发现: woc这个题一个cdq几行就搞定了! 题意简述 有\(n\)个哨站 ...

随机推荐

  1. mysql 主从笔记

    主库配置 一.修改主库配置文件 开启binlog,并设置server-id,每次修改配置文件后都要重启mysql服务才会生效 server-id = log-bin = mysql-bin binlo ...

  2. Java 基础 - 基本类型和引用类型

    ref: https://www.cnblogs.com/ysocean/p/8482979.html#_label2 ------------------ 这里再给大家普及一个概念,在 Java 中 ...

  3. Pipe进程之间的通信

    #_author:来童星#date:2019/12/11#Pipefrom multiprocessing import Process, Pipedef f(conn): conn.send([42 ...

  4. Windos DNS Client 缓存

    要查看 DNS 缓存,请在命令提示符下键入 ipconfig /displaydns. 要从 DNS 缓存中删除该项,请在命令提示符下键入 ipconfig /flushdns. ipconfig.e ...

  5. 全局CSS设置

    全局CSS设置 1.清除所有的标记的内外边距 body,ul,li,a,img,p,input{ margin:0; padding:0; } 2.去除项目符号或编号前面的符号 ul,ol,li{ l ...

  6. Linux 后台运行python .sh等程序,以及查看和关闭后台运行程序操作

    1.运行.sh文件 直接用./sh 文件就可以运行,但是如果想后台运行,即使关闭当前的终端也可以运行的话,需要nohup命令和&命令. (1)&命令 功能:加在一个命令的最后,可以把这 ...

  7. Tomcat点击项目名称,加载一个action请求

    <meta http-equiv="refresh" content="0;url=index.action">

  8. python 安装bs4

    1, 下载地址https://www.crummy.com/software/BeautifulSoup/#Download ------------------------------------- ...

  9. Mysql优化系列之查询优化干货1

    从这一篇开始,准备总结一些直接受用的sql语句优化,写sql是第二要紧的,第一要紧的,是会分析怎么查最快, 因为当你写过很多sql后,查询出结果已经不是目标,快,才是目标.另外,通过测试和比较的结果才 ...

  10. Git 比较两个分支之间的差异

    1.查看 dev 有,而 master 中没有的: git log dev ^master 2.查看 dev 中比 master 中多提交了哪些内容: git log master..dev 注意,列 ...