c2java 第8篇 网络流

Edmonds-Karp 算法: 使用bfs找增广路经,复杂度min(O(VE^2), O(EF)), 其中F是最大流的流量. 依据是
最大流最小割定理:
1. 对于任一流f和任一割c, 流量|f| = |c| <= c的容量。
2. f 是最大流 <==> 残留网络Gf没有增广路径 <==> 存在一个割,其容量等于f的流量。


应用例子
====
liquids in pipes, parts through assembly lines, current throw electrical networks.
1. 求一个无向图的边连通度, 意思是只有至少去掉k条边才能使得图不连通。例如树的边连通度为1,圈的为2。
答案就是最大流对应的最小割。


2. 二分图的最大匹配。
答案: 设图顶点分成L和F两部分,L 到F 的边容量是1, 增加两个顶点s到L, R到t,
容量为无穷大。


3. 最少路径覆盖所有顶点。minimum path cover.


语言注记
====
1. 如果Type是非基本类型,则Type[][] t = new Type[10][2] 实际相当于void* t[10][2] 与Type本身没有关系;
因此对于每个t[i][j] 都要new, 这里的问题是,new次数多了内存碎片影响有多大?
如果容量是整数,直接把v,cap,flow,res 编码为t[4*i+0, ..., 4*i+3]好了。


2. 下面加了一个iterator对象,这样做的最大好处是让上层应用不依赖底层的表示;以后如果换成链表上层

什么都不用改。

 代码:

 

运行结果:

/*
$ cat in.txt 
6 9 0 5
0 1 16 0 2 13
1 3 12
2 1 4 2 4 14
3 2 9 3 5 20
4 3 7 4 5 4
$ javac -g Flow.java && cat in.txt | java Main
<u,v> f/c:
<0,1>: 0/16 <0,2>: 4/13 <1,3>: 0/12 <2,1>: 0/4 <2,4>: 4/14 <3,2>: 0/9 <3,5>: 0/20 <4,3>: 0/7 <4,5>: 4/4 
<u,v> f/c:
<0,1>: 0/16 <0,2>: 11/13 <1,3>: 0/12 <2,1>: 0/4 <2,4>: 11/14 <3,2>: 0/9 <3,5>: 7/20 <4,3>: 7/7 <4,5>: 4/4 
<u,v> f/c:
<0,1>: 12/16 <0,2>: 11/13 <1,3>: 12/12 <2,1>: 0/4 <2,4>: 11/14 <3,2>: 0/9 <3,5>: 19/20 <4,3>: 7/7 <4,5>: 4/4 
<u,v> f/c:
<0,1>: 12/16 <0,2>: 11/13 <1,3>: 12/12 <2,1>: 0/4 <2,4>: 11/14 <3,2>: 0/9 <3,5>: 19/20 <4,3>: 7/7 <4,5>: 4/4 
max flow = 23
*/



你可能感兴趣的:(java)