最大网络流的Ford-Fulkerson 算法

/**************************************************** > File Name: max_flow.cpp > Author: Yuji CAO > Mail: [email protected] > Created Time: 六 6/10 16:42:38 2017 ****************************************************/

#include<map>
#include<vector>
#include<unordered_set>
#include<unordered_map>
#include<list>
#include<queue>
#include<deque>
#include<stack>
#include<iostream>
#include<set>
using namespace std;
class max_flow {
public:
    float ford_fulkson(vector<vector<float> >& c, int s, int t) {
        this->c = c;
        this->t = t;
        float ret = 0.0f;
        while (true) {
            float f_cur = numeric_limits<float>::max();
            unordered_set<int> visited;
            float flow = dfs(s, f_cur, visited);
            if (flow == 0.0f) break;
            ret += flow;
        }
        return ret;
    }
private:
    float dfs(int u, float f_cur, unordered_set<int>& visited) {
        visited.insert(u);      //标记已经访问过的节点
        if (u == t) return f_cur;
        float f_ret = 0.0f;     //从u出发到达终点的路径流量
        int to_node = -1;       //标记流量链路去向节点
        for (int i = 0; i < c.size(); ++i) {
            if (visited.count(i) != 0) continue;
            if (c[u][i] > 0.0f) {
                float f_curr = min(f_cur, c[u][i]);  //路径的当前跳的流量
                float tmp = dfs(i, f_curr, visited); //探索后续路径
                if (tmp > 0.0f) {                   //挑选所有的可选后续路径中流量最大的路径
                    f_ret = tmp;
                    to_node = i;
                    break;
                }
            }
        }
        if (to_node != -1) { //存在增广路径,生成残余网络
            c[u][to_node] -= f_ret; //正向路径容量减少
            c[to_node][u] += f_ret; //反向路径增加
            return min(f_cur, f_ret);
        } 
        return 0.0f;
    }

    vector<vector<float> > c;
    int t;
};

int main() {
    max_flow mf;
    int s, t;
    cin>>s>>t;
    int n;
    cin>>n;
    vector<vector<float> > c(n, vector<float>(n, 0.0f));
    int n_e;
    cin>>n_e;
    for (int i = 0; i < n_e; ++i) {
        int x, y;
        float tmp = 0.0f;
        cin>>x>>y>>tmp;
        c[x][y] = tmp;
    }

    float ret = mf.ford_fulkson(c, s, t);
    cout<<"answer:\t"<<ret<<endl;
    return 0;
}
点赞