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

 

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

标签: 网络流算法EdmondsKarp流量最大流
 34795人阅读 评论(12) 收藏 举报
 分类:

求网络流有很多算法,这几天学习了两种,记录一下EK算法。

首先是网络流中的一些定义:

V表示整个图中的所有结点的集合.
E表示整个图中所有边的集合.
G = (V,E) ,表示整个图.
s表示网络的源点,t表示网络的汇点.
对于每条边(u,v),有一个容量c(u,v)   (c(u,v)>=0),如果c(u,v)=0,则表示(u,v)不存在在网络中。相反,如果原网络中不存在边(u,v),则令c(u,v)=0.
对于每条边(u,v),有一个流量f(u,v).

一个简单的例子.网络可以被想象成一些输水的管道.括号内右边的数字表示管道的容量c,左边的数字表示这条管道的当前流量f.


网络流的三个性质:

1、容量限制:  f[u,v]<=c[u,v]
2、反对称性:f[u,v] = - f[v,u]
3、流量平衡:  对于不是源点也不是汇点的任意结点,流入该结点的流量和等于流出该结点的流量和。
只要满足这三个性质,就是一个合法的网络流.

最大流问题,就是求在满足网络流性质的情况下,源点 s 到汇点 t 的最大流量。


求一个网络流的最大流有很多算法 这里首先介绍 增广路算法(EK)

学习算法之前首先看了解这个算法中涉及到的几个图中的定义:


**残量网络

为了更方便算法的实现,一般根据原网络定义一个残量网络。其中r(u,v)为残量网络的容量。
r(u,v) = c(u,v) – f(u,v)
通俗地讲:就是对于某一条边(也称弧),还能再有多少流量经过。
Gf
 残量网络,Ef 表示残量网络的边集.


这是上面图的一个残量网络。残量网络(如果网络中一条边的容量为0,则认为这条边不在残量网络中。

r(s,v1)=0,所以就不画出来了。另外举个例子:r(v1,s) = c(v1,s) – f(v1,s) = 0 – (-f(s,v1)) = f(s,v1) = 4.

其中像(v1,s)这样的边称为后向弧,它表示从v1到s还可以增加4单位的流量。

但是从v1到s不是和原网络中的弧的方向相反吗?显然“从v1到s还可以增加4单位流量”这条信息毫无意义。那么,有必要建立这些后向弧吗?

显然,第1个图中的画出来的不是一个最大流。

但是,如果我们把s -> v2 -> v1 -> t这条路径经过的弧的流量都增加2,就得到了该网络的最大流。

注意到这条路径经过了一条后向弧:(v2,v1)。

如果不设立后向弧,算法就不能发现这条路径。

**从本质上说,后向弧为算法纠正自己所犯的错误提供了可能性,它允许算法取消先前的错误的行为(让2单位的流从v1流到v2)

注意,后向弧只是概念上的,在程序中后向弧与前向弧并无区别.


**增广路

增广路定义:在残量网络中的一条从s通往t的路径,其中任意一条弧(u,v),都有r[u,v]>0。


如图绿色的即为一条增广路。

看了这么多概念相信大家对增广路算法已经有大概的思路了吧。


**增广路算法

增广路算法:每次用BFS找一条最短的增广路径,然后沿着这条路径修改流量值(实际修改的是残量网络的边权)。当没有增广路时,算法停止,此时的流就是最大流。


**增广路算法的效率

设n = |V|,  m = |E|

每次增广都是一次BFS,效率为O(m),而在最坏的情况下需要(n-2增广。(即除源点和汇点外其他点都没有连通,所有点都只和s与t连通)

所以,总共的时间复杂度为O(m*n),所以在稀疏图中效率还是比较高的。


hdoj 1532是一道可以作为模板题目练手。

模板代码:

[cpp] view plaincopy
print?在CODE上查看代码片派生到我的代码片
  1. #include <cstdio>  
  2. #include <cstring>  
  3. #include <iostream>  
  4. #include <string>  
  5. #include <algorithm>  
  6. #include <map>  
  7. #include <vector>  
  8. using namespace std;  
  9. const int N = 1100;  
  10. const int INF = 0x3f3f3f3f;  
  11.   
  12. struct Node  
  13. {  
  14.     int to;//终点  
  15.     int cap; //容量  
  16.     int rev;  //反向边  
  17. };  
  18.   
  19. vector<Node> v[N];  
  20. bool used[N];  
  21.   
  22. void add_Node(int from,int to,int cap)  //重边情况不影响  
  23. {  
  24.     v[from].push_back((Node){to,cap,v[to].size()});  
  25.     v[to].push_back((Node){from,0,v[from].size()-1});  
  26. }  
  27.   
  28. int dfs(int s,int t,int f)  
  29. {  
  30.     if(s==t)  
  31.         return f;  
  32.     used[s]=true;  
  33.     for(int i=0;i<v[s].size();i++)  
  34.     {  
  35.         Node &tmp = v[s][i];  //注意  
  36.         if(used[tmp.to]==false && tmp.cap>0)  
  37.         {  
  38.             int d=dfs(tmp.to,t,min(f,tmp.cap));  
  39.             if(d>0)  
  40.             {  
  41.                 tmp.cap-=d;  
  42.                 v[tmp.to][tmp.rev].cap+=d;  
  43.                 return d;  
  44.             }  
  45.         }  
  46.     }  
  47.     return 0;  
  48. }  
  49.   
  50. int max_flow(int s,int t)  
  51. {  
  52.     int flow=0;  
  53.     for(;;){  
  54.         memset(used,false,sizeof(used));  
  55.         int f=dfs(s,t,INF);  
  56.         if(f==0)  
  57.             return flow;  
  58.         flow+=f;  
  59.     }  
  60. }  
  61. int main()  
  62. {  
  63.     int n,m;  
  64.     while(~scanf("%d%d",&n,&m))  
  65.     {  
  66.         memset(v,0,sizeof(v));  
  67.         for(int i=0;i<n;i++)  
  68.         {  
  69.             int x,y,z;  
  70.             scanf("%d%d%d",&x,&y,&z);  
  71.             add_Node(x,y,z);  
  72.         }  
  73.         printf("%d\n",max_flow(1,m));  
  74.     }  
  75. }  


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/509072.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java文件流操作注意

今天做了一个测试&#xff1a; Testpublic void fileOut() throws Exception {FileOutputStream out new FileOutputStream(new File("test.txt"), false);out.write("1".getBytes());out.write("2".getBytes());File file new File("tes…

try代码块中出现异常后try内程序会继续执行还是直接抛出异常?

Testpublic void excp() {try {int i 1/0;System.out.println(1);}catch (Exception e) {e.printStackTrace();// TODO: handle exception}System.out.println(22);}输出&#xff1a; java.lang.ArithmeticException: / by zero at task.ExceedActiveTimeClearTask.excp(Excee…

java文件重命名失败问题

我记得之前也遇到这个问题后来找了几个小时才找到问题&#xff0c;这次又花了一个小时找出这个问题&#xff0c;发现是自己的文件流没有关闭&#xff0c;一定要切记&#xff0c;当对文件重命名操作的时候一定要先把操作改文件的文件流关闭之后再进行重命名的操作&#xff0c;切…

equalsignorecase用法

来源&#xff1a;百度知道 解释&#xff1a; public boolean equalsIgnoreCase(String anotherString)将此 String 与另一个 String 进行比较&#xff0c;不考虑大小写。如果两个字符串的长度相等&#xff0c;并且两个字符串中的相应字符都相等&#xff08;忽略大小写&#xf…

利用TF-IDF提取新闻文章摘要

文章&#xff1a;http://www.ruanyifeng.com/blog/2013/03/automatic_summarization.html

【转载】LinkedHashMap和HashMap区别

HashMap,LinkedHashMap,TreeMap都属于Map Map 主要用于存储键(key)值(value)对&#xff0c;根据键得到值&#xff0c;因此键不允许键重复,但允许值重复。 HashMap 是一个最常用的Map,它根据键的HashCode 值存储数据,根据键可以直接获取它的值&#xff0c;具有很快的访问速度。…

java英文拼写检查并自动纠正

SpellCorrect原理&#xff1a;https://www.cnblogs.com/jianxinzhou/p/4740392.html 项目源码&#xff1a; package com.xq.algorithm;import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import j…

java Trie实现英文单词查找树 搜索自动提示

原理解释文章&#xff1a;https://blog.csdn.net/beiyetengqing/article/details/7856113 代码应用&#xff1a; wordTrie.txt(工具类)&#xff1a; package com.xq.algorithm;import java.util.ArrayList; import java.util.List;/*** * <p>Title:</p>* <p>…

java HashMap实现中文分词器 应用:敏感词过滤实现

今天下午部门内部技术分享是分词器算法。这次的主讲是大名鼎鼎的Ansj分词器的作者-孙健。 作者简介&#xff1a; Ansj分词器作者 elasticsearch-sql&#xff08;elasticsearch的sql插件&#xff09;作者&#xff0c;支持sql查询 nlp-lang自然语言工具包发起人 NLPCN&#xff…

java字典树(Trie)实现中文模糊匹配

原理解释&#xff1a; java实现&#xff1a;https://blog.csdn.net/yuhk231/article/details/51539840 c实现&#xff1a;https://blog.csdn.net/qq_31175231/article/details/77827324 代码模板&#xff1a;缺点&#xff0c;只能检索出在一个分支中的前缀匹配内容 package co…

Word2vec加TextRank算法生成文章摘要

依赖包&#xff1a;https://download.csdn.net/download/dreamzuora/10853874 代码&#xff1a; String document "算法可大致分为基本算法、数据结构的算法、数论算法、计算几何的算法、图的算法、动态规划以及数值分析、加密算法、排序算法、检索算法、随机化算法、并行…

hanlp中文分词、提取摘要关键字、语句分析、智能推荐

hanlp资源&#xff1a; hanlp介绍&#xff1a;http://hanlp.linrunsoft.com/ hanlp下载&#xff1a;https://github.com/hankcs/HanLP hanlp(分词)使用&#xff1a;https://blog.csdn.net/nima1994/article/details/72819973 hanlp1.7:https://github.com/hankcs/HanLP/tree/v1…

TextRank、BM25算法提取关键字、文章自动摘要优秀文章保存

转载地址&#xff1a;http://www.hankcs.com/nlp/textrank-algorithm-java-implementation-of-automatic-abstract.html

set 用法

Set常用用法 2013-04-22 19:24 86508人阅读 评论(1) 收藏 举报分类&#xff1a;CPlus&#xff08;54&#xff09; set集合容器&#xff1a;实现了红黑树的平衡二叉检索树的数据结构&#xff0c;插入元素时&#xff0c;它会自动调整二叉树的排列&#xff0c;把元素放到适当的位置…

去掉标点符号

//去掉标点符号、空格title title.replaceAll("[\\pP\\p{Punct}| ]", "");

C语言向文件写入内容并读取显示

将学生信息&#xff08;姓名、年龄、学号和平均分&#xff09;写入文件&#xff0c;然后读取显示出来。要求&#xff1a;从控制台输入学生信息&#xff1b;可以输入任意数目的学生信息&#xff1b;文件每行存储一条学生信息&#xff0c;姓名、年龄、学号、平均分以tab(\t)为分隔…

C语言main()主函数执行完毕后是否会再执行一段代码

C语言main()主函数执行完毕后是否会再执行一段代码 分享到&#xff1a;QQ空间新浪微博腾讯微博豆瓣人人网main() 主函数执行完毕后&#xff0c;是否可能会再执行一段代码&#xff1f;给出说明。main主函数是所有程序必须具备的函数&#xff0c;是C/C人员一接触代码就知道的函数…

java 操作redis

//连接redis &#xff0c;redis的默认端口是6379Jedis jedis new Jedis ("localhost",6379); //验证密码&#xff0c;如果没有设置密码这段代码省略jedis.auth("password"); jedis.connect();//连接jedis.disconnect();//断开连接Set<String> keys…

C语言用递归求斐波那契数,让你发现递归的缺陷和效率瓶颈

C语言用递归求斐波那契数&#xff0c;让你发现递归的缺陷和效率瓶颈 分享到&#xff1a;QQ空间新浪微博腾讯微博豆瓣人人网递归是一种强有力的技巧&#xff0c;但和其他技巧一样&#xff0c;它也可能被误用。一般需要递归解决的问题有两个特点&#xff1a;存在限制条件&#xf…

【转载保存】java四种线程池的使用

https://blog.csdn.net/qq_31441667/article/details/78830395