老师上课讲的网络流问题,牵扯到几个反相弧,增广路径,残量网络 的概念,愣是一节课神游没听明白,后来只能自己回家搞。

这篇博文我看了以后觉得十分有帮助就拿来了,比较清楚地介绍了它的基本想法思路。

http://www.cnblogs.com/kuangbin/archive/2011/07/26/2117636.html

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

最近又复习了下最大流问题,每次看这部分的内容都会有新的收获。可以说最大流问题的资料网上一搜一大把,根本没有必要自己写;但是大部分资料上的专业术语太多了,初学很难理解,至少我当年学这部分的时候前几次就没有看懂。所以我准备备份一点个人的理解。

图-1

如图-1所示,在这个运输网络中,源点S和汇点T分别是1,7,各边的容量为C(u,v)。图中红色虚线所示就是一个可行流。标准图示法如图-2所示:

其中p(u,v) / c(u,v)分别表示该边的实际流量与最大容量。

关于最大流

熟悉了什么是网络流,最大流也就很好理解了。就是对于任意的u∈V-{s},使得p(s,u)的和达到最大。上面的运输网络中,最大流如图-3所示:MaxFlow=p(1,2)+p(1,3)=2+1=3。

在介绍最大流问题之前,先介绍几个概念:残余网络,增广路径,反向弧,最大流定理以及求最大流的Ford-Fulkerson方法。

残余网络 增广路径 反向弧

观察下图-4,这种状态下它的残余网络如图-5所示:

也许现在你已经知道什么是残余网络了,对于已经找到一条从S 到T的路径的网络中,只要在这条路径上,把C(u,v)的值更新为C(u,v)-P(u,v),并且添加反向弧C(v,u)。对应的增广路径Path为残留网络上从S到T的一条简单路径。图-4中1,2,4,7就是一条增广路径,当然还有1,3,4,7。

此外在未做任何操作之前,原始的有向图也是一个残余网络,它仅仅是未做任何更新而已。

最大流定理

如果残留网络上找不到增广路径,则当前流为最大流;反之,如果当前流不为最大流,则一定有增广路径。

Ford-Fulkerson方法

介绍完上面的概念之后,便可以用Ford-Fulkerson方法求最大流了。为什么叫Ford-Fulkerson方法而不是算法,原因在于可以用多种方式实现这一方法,方式并不唯一。下面介绍一种基于广度优先搜索(BFS)来计算增广路径P的算法:Edmonds-Karp算法。

算法流程如下:

设队列Q:存储当前未访问的节点,队首节点出队后,成为已检查的标点;

Path数组:存储当前已访问过的节点的增广路径;

Flow数组:存储一次BFS遍历之后流的可改进量;

Repeat:

Path清空;

源点S进入Path和Q,Path[S]<-0,Flow[S]<-+∞;

While Q非空 and 汇点T未访问 do

Begin

队首顶点u出对;

For每一条从u出发的弧(u,v) do

If v未访问 and 弧(u,v) 的流量可改进;

Then Flow[v]<-min(Flow[u],c[u][v]) and v入队 and Path[v]<-u;

End while

If(汇点T已访问)

Then 从汇点T沿着Path构造残余网络;

Until 汇点T未被访问

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

1   #include  < iostream >
 2   #include  < queue >
 3   using   namespace  std;
 4  
 5   const   int  N  =   210 ;
 6   const   int  INF  =   0x7FFFFFFF ;
 7   int  n,m,map[N][N],path[N],flow[N],start,end;
 8   queue < int >  q;
 9  
10   int  bfs(){
11        int  i,t;
12        while ( ! q.empty()) q.pop();
13       memset(path, - 1 , sizeof (path));
14       path[start] = 0 ,flow[start] = INF;
15       q.push(start);
16        while ( ! q.empty()){
17           t = q.front();
18           q.pop();
19            if (t == end)  break ;
20            for (i = 1 ;i <= m;i ++ ){
21                if (i != start  &&  path[i] ==- 1   &&  map[t][i]){
22                   flow[i] = flow[t] < map[t][i] ? flow[t]:map[t][i];
23                   q.push(i);
24                   path[i] = t;
25               }
26           }
27       }
28        if (path[end] ==- 1 )  return   - 1 ;
29        return  flow[m];                    // 一次遍历之后的流量增量
30   }
31   int  Edmonds_Karp(){
32        int  max_flow = 0 ,step,now,pre;
33        while ((step = bfs()) !=- 1 ){           // 找不到增路径时退出
34           max_flow += step;
35           now = end;
36            while (now != start){
37               pre = path[now];
38               map[pre][now] -= step;       // 更新正向边的实际容量
39               map[now][pre] += step;       // 添加反向边
40               now = pre;
41           }
42       }
43        return  max_flow;
44   }
45   int  main(){
46        int  i,u,v,cost;
47        while (scanf( " %d %d " , & n, & m) != EOF){
48           memset(map, 0 , sizeof (map));
49            for (i = 0 ;i < n;i ++ ){
50               scanf( " %d %d %d " , & u, & v, & cost);
51               map[u][v] += cost;            // not just only one input
52           }
53           start = 1 ,end = m;
54           printf( " %d\n " ,Edmonds_Karp());
55       }
56        return   0 ;
57   }
58

网络流——最大流问题相关推荐

  1. 图论--网络流最大流问题

    问题表述:给定一幅图(n个结点,m条边),每一条边有一个容量,现在需要将一些物品从结点s(称为源点)运送到结点t(称为汇点),可以从其他结点中转,求最大的运送量. 在介绍最大流问题的解决方法之前,先介 ...

  2. 网络流--最大流问题

    一.什么是最大流问题 简单来说,就是在有向网络图中,单位时间内,从开始点到结束点能通过的最大流量 许多应用都包含了流量问题,例如,公路系统中有车辆流,控制系统中有信息流,供水系统中有水流,金融系统中有 ...

  3. uva 753(网络流最大流)

    网络流最大流问题,这里使s=0,使s与所有的插头相连,最大通量为1,然后插头和转换器相连,最大通量为1,转换器和转换器相连,因为有无限个,所以为inf,然后转换器和插座连,最大通量为1,插座和t相连, ...

  4. 网络流之最大流算法(EdmondsKarp)

    网络流之最大流算法(EdmondsKarp) 标签: 网络流算法EdmondsKarp流量最大流 2014-03-11 18:05 34795人阅读 评论(12) 收藏 举报  分类: 图论~~网络流 ...

  5. ACM基础知识及算法

    ACM 算法   难度 数据结构 栈 栈     1 单调栈       队列 一般队列     1 优先队列/单调队列     1 循环队列     2 双端队列     2 链表 一般链表     ...

  6. 数据结构与算法分析C++语言描述(第四版)图论学习记录

    我对 9.3.1节中无权最短路径算法,进行了一点修改,对书中例子也进行了测试,发现居然也适用于有权最短路径求解. 对 赋权图最短路径求解,我仍然使用和 9.3.1节中求解无权图最短路径同样的方式,参见 ...

  7. 【网络流】最大流问题(EK算法带模板,Dinic算法带模板及弧优化,ISAP算法带模板及弧优化)上下界网络流

    本blog重点是代码 网络流的相关概念 流网络(flow network) 流(flow) 网络的流 残留网络(residual network) 增广路径(augmenting path) Edmo ...

  8. 网络流算法学习笔记——最大流问题基本概念和Ford-Fulkerson方法(标号法C++实现)

    屈婉玲<算法设计与分析>第2版第7章网络流算法学习笔记. 基本概念 最大流问题,相当于有从s到t的供水系统,每段路径都有限定流量,除了s.t两地外,每个中间点都不能滞留,从s流入多少,就从 ...

  9. 网络流(一)最大流问题EdmondsKarp和最小费用最大流

    一.最大流问题 如下图所示,假设需要把一些物品从结点S(称为源点)运送到结点t(称为汇点),可以从其它结点中转.每条边上的权值(左图)表示该条路径最多能运送的物品数,右图边上的权值第一个数表示实际运送 ...

最新文章

  1. 构建dubbo分布式平台-maven构建根项目
  2. linux卸载dev中的设备,Linux /dev 常见特殊设备介绍与应用
  3. 计算机性能在线测评,关于电脑性能测试的常见的几大方法
  4. Jzoj4840 小W砍大树
  5. tornado 获取html,python使用tornado实现简单爬虫
  6. inotify之文件系统事件监控使用入门
  7. 实现自动文本摘要(python,java)
  8. mule esb_Mule ESB –入门
  9. 一个简单的json解析器
  10. centos8 开启ftp服务
  11. IDEA高级玩法:集成JIRA、UML类图插件、SSH、FTP、Database管理...
  12. (转载)MySQL基础(非常全)
  13. android 判断wifi强弱,Android:通过WifiManager监听Wifi信号强弱
  14. Java的getbytes()方法使用
  15. 【运动学】基于matlab EKF姿态估计【含Matlab源码 1638期】
  16. JavaScript获取汉字的区位码
  17. ubuntu使用ffmpeg截取视频
  18. C语言 三子棋 游戏
  19. 大数据BI工具Tableau学习【第三期】:数据类型,功能区和卡参考,文件类型(连接方式)
  20. 如何将CVAT的docker镜像上传到华为云镜像中心SWR

热门文章

  1. C#之三十七 实体类
  2. linux sftp与ftp,Linux ftp和sftp命令
  3. kafka是什么?深刻理解kafka
  4. ContentProvider android:exported = “true”
  5. Jmeter——Jmeter之命令行测试
  6. 【webapp】开发手机版WEBAPP MOBILE APP
  7. SSH登录的两种方式
  8. Ubuntu查看一些版本 1
  9. 软件测试工程师应该具备哪些能力?
  10. 爱读掌阅java版_爱读掌阅app官方下载-爱读掌阅旧版本 - 超好玩