一、算法理论

【基本思想】

反复寻找源点s到汇点t之间的增广路径,若有,找出增广路径上每一段[容量-流量]的最小值delta,若无,则结束。
在寻找增广路径时,可以用BFS来找,并且更新残留网络的值(涉及到反向弧)。
而找到delta后,则使最大流值加上delta,更新为当前的最大流值。

【算法详解】

这么一个图,求源点1到汇点4的最大流。

由于我是通过模版真正理解ek的含义,所以先上代码,通过分析代码,来详细叙述ek算法。

  1. #include <iostream>
  2. #include <queue>
  3. #include<string.h>
  4. using namespace std;
  5. #define arraysize 201
  6. int maxData = 0x7fffffff;
  7. int capacity[arraysize][arraysize]; //记录残留网络的容量
  8. int flow[arraysize]; //标记从源点到当前节点实际还剩多少流量可用
  9. int pre[arraysize]; //标记在这条路径上当前节点的前驱,同时标记该节点是否在队列中
  10. int n,m;
  11. queue<int> myqueue;
  12. int BFS(int src,int des)
  13. {
  14. int i,j;
  15. while(!myqueue.empty()) //队列清空
  16. myqueue.pop();
  17. for(i=1;i<m+1;++i)
  18. {
  19. pre[i]=-1;
  20. }
  21. pre[src]=0;
  22. flow[src]= maxData;
  23. myqueue.push(src);
  24. while(!myqueue.empty())
  25. {
  26. int index = myqueue.front();
  27. myqueue.pop();
  28. if(index == des) //找到了增广路径
  29. break;
  30. for(i=1;i<m+1;++i)
  31. {
  32. if(i!=src && capacity[index][i]>0 && pre[i]==-1)
  33. {
  34. pre[i] = index; //记录前驱
  35. flow[i] = min(capacity[index][i],flow[index]); //关键:迭代的找到增量
  36. myqueue.push(i);
  37. }
  38. }
  39. }
  40. if(pre[des]==-1) //残留图中不再存在增广路径
  41. return -1;
  42. else
  43. return flow[des];
  44. }
  45. int maxFlow(int src,int des)
  46. {
  47. int increasement= 0;
  48. int sumflow = 0;
  49. while((increasement=BFS(src,des))!=-1)
  50. {
  51. int k = des; //利用前驱寻找路径
  52. while(k!=src)
  53. {
  54. int last = pre[k];
  55. capacity[last][k] -= increasement; //改变正向边的容量
  56. capacity[k][last] += increasement; //改变反向边的容量
  57. k = last;
  58. }
  59. sumflow += increasement;
  60. }
  61. return sumflow;
  62. }
  63. int main()
  64. {
  65. int i,j;
  66. int start,end,ci;
  67. while(cin>>n>>m)
  68. {
  69. memset(capacity,0,sizeof(capacity));
  70. memset(flow,0,sizeof(flow));
  71. for(i=0;i<n;++i)
  72. {
  73. cin>>start>>end>>ci;
  74. if(start == end) //考虑起点终点相同的情况
  75. continue;
  76. capacity[start][end] +=ci; //此处注意可能出现多条同一起点终点的情况
  77. }
  78. cout<<maxFlow(1,m)<<endl;
  79. }
  80. return 0;
  81. }

显而易见capacity存变的流量,进行ek求解。

对于BFS找增广路:

  • flow[1]=INF,pre[1]=0;

源点1进队列,开始找增广路,capacity[1][2]=40>0,则flow[2]=min(flow[1],40)=40;

capacity[1][4]=20>0,则flow[4]=min(flow[1],20)=20;

capacity[2][3]=30>0,则flow[3]=min(folw[2]=40,30)=30;

capacity[2][4]=30,但是pre[4]=1(已经在capacity[1][4]这遍历过4号点了)

capacity[3][4].....

当index=4(汇点),结束增广路的寻找

传递回increasement(该路径的流),利用前驱pre寻找路径

路径也自然变成了这样:

  • flow[1]=INF,pre[1]=0;

  源点1进队列,开始找增广路,capacity[1][2]=40>0,则flow[2]=min(flow[1],40)=40;

  capacity[1][4]=0!>0,跳过

capacity[2][3]=30>0,则flow[3]=min(folw[2]=40,30)=30;

capacity[2][4]=30,pre[4]=2,则flow[2][4]=min(flow[2]=40,20)=20;

capacity[3][4].....

当index=4(汇点),结束增广路的寻找

传递回increasement(该路径的流),利用前驱pre寻找路径

图也被改成这样:

接下来同理:

这就是最终完成的图,最终sumflow=20+20+10=50(这个就是最大流的值)

二、算法分析

  • 时间复杂度为O(m2n)
  • 而接下来的Dinic算法的时间复杂度为O(n2m)

最大流——EK算法的更多相关文章

  1. 二分图的最大匹配——最大流EK算法

    序: 既然是个图,并且求边数的最大值.那么这就可以转化为网络流的求最大流问题. 只需要将源点与其中一子集的所有节点相连,汇点与另一子集的所有节点相连,将所有弧的流量限制置为1,那么最大流 == 最大匹 ...

  2. 最大流EK算法/DINIC算法学习

    之前一直觉得很难,没学过网络流,毕竟是基础知识现在重新来看. 定义一下网络流问题,就是在一幅有向图中,每条边有两个属性,一个是cap表示容量,一个是flow 表示流过的流量.我们要求解的问题就是从S点 ...

  3. (通俗易懂小白入门)网络流最大流——EK算法

    网络流 网络流是模仿水流解决生活中类似问题的一种方法策略,来看这么一个问题,有一个自来水厂S,它要向目标T提供水量,从S出发有不确定数量和方向的水管,它可能直接到达T或者经过更多的节点的中转,目前确定 ...

  4. vector实现最大流EK算法

    序: 在之前的文章中实现了不利用STL实现EK算法,效率也较高.这次我们企图简化代码,减少变量的使用与手写模拟的代码. 注意:vector等STL的container在不开O2优化的时候实现同一个效果 ...

  5. 最大流EK算法模板

    最近学了下最大流算法,大概思想算是懵懵懂懂了,现在想把模板记录下来,以备后面深刻学习之用. #include<cstdio> #include<cstring> using n ...

  6. POJ-1459(最大流+EK算法)

    Power Network POJ-1459 这题值得思索的就是特殊的输入,如何输入一连串字符.这里采用的方法是根据输入已知的输入格式,事先预定好要接受的数据类型. 这里套用的板子也是最大流的模板,但 ...

  7. 【转】最大流EK算法

    转自:http://www.cnblogs.com/kuangbin/archive/2011/07/26/2117636.html 图-1 如图-1所示,在这个运输网络中,源点S和汇点T分别是1,7 ...

  8. POJ1273 最大流 EK算法

    套了个EK的模板 //#pragma comment(linker, "/STACK:16777216") //for c++ Compiler #include <stdi ...

  9. 最大流EK算法

    给定一个有向图G=(V,E),把图中的边看作 管道,每条边上有一个权值,表示该管道 的流量上限.给定源点s和汇点t,现在假设 在s处有一个水源,t处有一个蓄水池,问从 s到t的最大水流量是多少? 网络 ...

随机推荐

  1. CSS 中定位方式有几种,说明他们的意义

    1.static  默认定位方式 显示为没有设置定位时的位置 2.fixed(固定定位)  他所相对固定的对象是可视窗口,与其他无关.以浏览器窗口作为参考进行定位 3.relative(相对定位) 元 ...

  2. C#实现打印

    C#实现导出pdf文件,打印 using System; using System.Collections.Generic; using System.Linq; using System.Web; ...

  3. Redis工具之Jedis

    //jedis的连接池 public void test1(){ //创建连接池配置对象 JedisPoolConfig poolConfig = new JedisPoolConfig(); poo ...

  4. 对TCP三次握手四次分手还不清楚,超简单解析

      关于TCP三次握手四次分手,之前看资料解释的都很笼统,很多地方都不是很明白,所以很难记,前几天看的一个博客豁然开朗,可惜现在找不到了.现在把之前的疑惑总结起来,方便一下大家. 先上个TCP三次握手 ...

  5. mysql的数据操作和内置功能总结

    一.数据的增删改查 1.插入数据 a.插入完整数据(顺序插入) INSERT INTO 表名(字段1,字段2,字段3…字段n) VALUES(值1,值2,值3…值n); INSERT INTO 表名 ...

  6. Spring笔记2

    Bean生命周期 1 实例化 2 注入属性 3 BeanNameAware 4 BeanFactoryAware 5 ApplicationContextAware 6 BeanPostProcess ...

  7. emlog博客插件分享openSug

    emlog博客插件百度搜索下拉提示框openSug.js发布上线啦: 下载:https://www.opensug.org/faq/.../opensug.emlog_v1.0.0.zip[~4KB]

  8. ODBC error in PHP: “No tuples available at this result index”

    ODBC error in PHP: “No tuples available at this result index” 在执行存储过程的时候发生如题的错误,在stackoverflow上找到了相同 ...

  9. docker配置与实践#可以好好看看

    Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源.Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级.可移植的容器中,然后发布到任何流行的 L ...

  10. ctf题目writeup(7)

    2019.2.10 过年休息归来,继续做题. bugku的web题,地址:https://ctf.bugku.com/challenges 1. http://123.206.87.240:8002/ ...