Ford-Fulkerson
keyword
最大流 Ford-Fulkerson C++
入力
流量を表す行列、sourceの番号、sinkの番号(いずれも0-base)を与える。行列については流れないとき0(実は負でも良いけど)を入れること。流量が実数の場合はアルゴリズムが終了する保証はない。
出力
sourceからsinkへの最大の流量を返す。必要に応じてflow matrixを返すこともできる。
計算量
時間計算量 O(m*maxflow) (maxflowはmatrixの最大の要素)。ただし整数の場合のみ。
空間計算量 O(n*n)。疎でも密でも変わらず。
注釈
残余グラフは実は作らなくても他ので代用が効く。メモリが厳しいときはここを削る。
動作は未検証。
template<typename T> T FordFulkersonByMatrix(vector< vector<T> > &matrix, int source, int sink){ int n = matrix.size(); T maxCost = (T)0; vector< vector<T> > flowMat(n, vector<T>(n,0)), resMat = matrix; for(int i=0; i<n; i++)for(int j=0; j<n; j++) maxCost = max(maxCost,matrix[i][j]); while(1){ stack<int> st; vector<int> parent(n,-1); st.push(source); while(!st.empty() && parent[sink] == -1){ int tp = st.top(); st.pop(); for(int i=0; i<n; i++){ if(parent[i] == -1 && resMat[tp][i] > 0){ st.push(i); parent[i] = tp; } } } if(parent[sink] == -1) break; T minCost = maxCost; for(int i=sink; i!=source; i = parent[i]){ minCost = min(minCost, resMat[parent[i]][i]); } for(int i=sink; i!=source ; i = parent[i]){ flowMat[parent[i]][i] += minCost; flowMat[i][parent[i]] -= minCost; resMat[parent[i]][i] -= minCost; resMat[i][parent[i]] += minCost; } } return accumulate(flowMat[source].begin(), flowMat[source].end(), (T)0); }