首先要利用网络流去给题目设计算法,就要满足网络流的基本要求:
—容量限制
—流守恒性
—反对称性
—上面三个性质可以在正流和净流上定义,这样定义的结果就是,
既可以满足一些限制(容量限制可以具体为别的限制),
又可以使得有“流”的结果。进出是一样的,还可以在后面讨论最大的结果。
流的简单性质:点组的性质
—f(X,X) = 0;
—f(X,Y) = -f(Y,X);
—f(X或Y,Z) = 和,但是需要X,Y不相交;
最大流最小割定理
—三条性质保证定理
—流网络的割:
—任意流和在这个流下定义的一个割(源点和汇点必须分属两个分区)流是一样的。
—|f| = f(S, T);
—最大流的上限是割容量
—|f| <= c(S, T);
—残留网络:
—关于计算残留网络容量,对称边内的流在本条边的流变负流,使得本条边容量变大
—对于这个算法的解释是:先抵消反向的流,然后再填充这边奔来的残留网络容量
—残留网络的边和原图边的关系
—f(u,v) < c(u,v) => (u,v), (v,u) 都存在
—f(u,v) = c(u,v) 且不为0 => (u,v)不存在,(v,u)存在
—c(u,v) = c(v,u) => 都不存在
——(u,v)在残留网络中存在,则需要(u,v)或者(v,u)在原图中存在,|Ef| <= 2|E|
—流可以顺序叠加:f是G的一个流,f'是Gf的一个流,那么|f+f'| = |f| + |f'|
—增广路径:
—寻找增广路径:广度优先,深度优先
—找路径,相应流,叠加流
—最大流最小割定理
—三条等价命题
—命题给设计算法的启示
—一个最大流是任意割的容量
—最大流等价残留网络不存在增广路径
最大流算法分析
—详情看下面博文
—http://blog.csdn.net/abcjennifer/article/details/5556455
—基础算法:Ford - Fulkerson 方法
1 Ford-Fulkerson 方法 (G,s,t) 2 将各边上流量 f 初始化为 0 3 while 存在一条增广路径 p 4 do 沿路径 p 增广流量 f 5 return f
—这个算法只是利用最大流最小割的一个思想
—广度优先寻找增广路径:Edmonds - Karp 算法
1 Shortest Augmenting Path 2 x <-- 0 3 while 在残量网络 Gx 中存在增广路 s ~> t 4 do 找一条最短的增广路径 P 5 delta <-- min{rij:(i,j) 属于 P} 6 沿 P 增广 delta 大小的流量 7 更新残量网络 Gx 8 return x
—虽然使用BFS使得复杂度限制在O(VE2),但是由于每次寻找增广路径都是一个BFS的过程,
需要搜索预最短路径之前的所有路径,这样频繁的BFS使得算法由很多冗余
—同时运用DFS和BFS查找增广路径并且计算最大流:Dinic 算法
—算法过程:
—先进行一遍BFS标记所有点的深度d[i]
—保留d[i]+1 = d[j]的边
—这样由于d[i]是每个点从源点到i的最短距离,保留这样的边使得,每条路径都是源点到该点的最短路径
—DFS遍历所有到汇点t的最短路径,使用F-F的思想求得最大流
—重复
—网上一个人的对算法的理解:http://blog.csdn.net/zxy_snow/article/details/6176628
网络流题目
—PIGS poj-1149
—http://www.cnblogs.com/sleeper-qp/archive/2012/07/23/2605253.html
—构图在“算分”文件夹下pdf里
—Alice's Chance poj-1698
—在POJ文件夹里面有代码
—最大流题目的解题过程
—构图:
—关键是每周的周一到周日都有一套结点:
否则,按三部图的话,无法判定某天day的工作是来自哪部film,而且也不知道每周到源点应该容量多大
—不能在同一天干两部电影:天的顶点流出的边的容量要设置成1,这样在左边只能选择一个电影流入
—最大流为电影需要天数的总和
——各自为一套的题目:
—周-天:本身固有7条边,而且每天进入周的流量其实有区分的(这题中,电影不同)
—最大流算法:一般用Dinic算法
—外层循环是BFS,标记深度
—由标记和新图DFS,循环当前图的所有可增广路径,然后更新流
—构图:
—Floyd求任意点最短路径
—按二分法设定最远点的最近距离,构建流图:机器和奶牛之间的连线
—源点和机器之间连接M容量的边
—奶牛和汇点连接容量为1的边
—最大流算法
—得到奶牛数量大小的流量
—EK算法:每次流量加1,多一头牛可以找到机器