這部分內容在《算法競賽入門經典》——劉汝佳 里面講的已經很詳細了。但里面對於反向流量的作用是沒有說明的。這里只說一下反向流量的作用。
推薦上http://www.cnblogs.com/g0feng/archive/2012/05/29/2524749.htm看下。
反向流量能夠讓后面的流自我調整。
例如當前狀態下
當前狀態下如何尋找?
用a表示殘量, cap表示容量,很明顯,3-4這條路不是最優的.
此時BFS, 會得到 a[2] = 2, a[4] = 2, a[3] = 1 (提示:cap[4][3]-flow[4][3]=1), a[5]=1, a[6]=1, a[7]=1
更新流量得到
可以看到,通過方向流量,使得網絡流自我調整到最優。
附上代碼:
#include <iostream> #include <queue> #include <cstdio> #include <cstring> using namespace std; const int maxn = 20; const int INF = (1<<30); int cap[maxn][maxn], flow[maxn][maxn]; int n; int EdmondsKarp(int s, int t) { int p[maxn], a[maxn]; queue<int> q; memset(flow, 0, sizeof(flow)); int f = 0; while(true) { memset(a, 0, sizeof(a)); a[s] = INF; q.push(s); while(!q.empty()) { //BFS 找增廣路 int u = q.front(); q.pop(); for(int v=1; v<=n; v++) if(!a[v] && cap[u][v]>flow[u][v]){ //找到新節點v p[v] = u; q.push(v); a[v] = min(a[u], cap[u][v]-flow[u][v]); } } if(a[t] == 0) break; //找不到,則當前流已經是最大流 for(int u=t; u != s; u = p[u]) { //從匯點往回走 flow[p[u]][u] += a[t]; //更新正向流量 flow[u][p[u]] -= a[t]; //更新反向流量 } f += a[t]; //更新從 s 流出的流量 } return f; }