最大流算法小结
最近在看网络流,把几个常用的算法总结下,正确性的证明和一些理论的东西就不写了,参看算法导论和神牛们的论文,我只写算法的理解和实现模板。 Ford-Fulkerson方法 每次找增广路,把这条路上的所有点的流量加上这条路上的残余容量,再找新的增广路,直到找不到为止,它有很多种实现方法,下面给出算法导论上的伪代码
Ford_Fulkerson( G, s, t )
{ for each edge( u, v )∈E[G] do f[u,v] = 0 f[v,u]= 0 while there exists a path p from s to t in the residual network Gf do Cf(p) = min { Cf(u,v) | (u,v) is in p } for each edge(u,v) in p do f[u,v] += Cf(p) f[v,u] = - f[u,v]
Edmonds-Karp算法
就是用广度优先搜索来实现Ford-Fulkerson方法中对增广路径的计算,时间复杂度为O(VE
2 )
(代码参考NOCOW)
#define
VMAX 201
int
n, m;
//
分别表示图的边数和顶点数
int
c[VMAX][VMAX];
int
Edmonds_Karp(
int
s,
int
t )
{ // 输入源点和汇点 int p, q, queue[VMAX], u, v, pre[VMAX], flow = 0 , aug; while ( true ) { memset(pre, - 1 , sizeof (pre)); // 记录父节点 for ( queue[p = q = 0 ] = s; p <= q; p ++ ) { // 广度优先搜索 u = queue[p]; for ( v = 0 ; v <m && pre[t] < 0 ; v ++ ) if ( c[u][v] > 0 && pre[v] < 0 ) pre[v] = u, queue[ ++ q] = v; if ( pre[t] >= 0 ) break ; } if ( pre[t] < 0 ) break ; // 不存在增广路 aug = 0x7fff ; // 记录最小残留容量 for ( u = pre[v = t]; v != s; v = u,u = pre[u] ) if (c[u][v] < aug) aug = c[u][v]; for ( u = pre[v = t]; v != s; v = u,u = pre[u] ) c[u][v] -= aug, c[v][u] += aug; flow += aug; } return flow; }
转载于:https://www.cnblogs.com/ACAC/archive/2010/05/17/1737767.html