Cod sursa(job #1250985)

Utilizator gabrieligabrieli gabrieli Data 28 octombrie 2014 20:29:34
Problema Flux maxim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.49 kb
#include <algorithm>
#include <fstream>
#include <queue>
#include <vector>
using namespace std;

void bfs(
        const int source,
        vector<int>& parent,
        const vector<vector<int>>& capacity, 
        const vector<vector<int>>& G) {
    fill(parent.begin(), parent.end(), -1);
    
    queue<int> Q;
    Q.push(source);
    parent[source] = source;
    
    while (!Q.empty()) {
        int u = Q.front(); Q.pop();
        for (int v : G[u]) if (parent[v] == -1 && capacity[u][v]) {
            Q.push(v);
            parent[v] = u;
        }
    }
}

inline int findMaxFlow(
        int start,
        const vector<int>& parent,
        const vector<vector<int>>& capacity) {
    int flow = numeric_limits<int>::max();
    
    for (; start != parent[start] && flow; start = parent[start])
        flow = min(flow, capacity[parent[start]][start]);
    
    return flow;
}

inline void augmentFlow(
        int start,
        const int flow,
        const vector<int>& parent,
        vector<vector<int>>& capacity) {
    for (; start != parent[start]; start = parent[start]) {
        capacity[parent[start]][start] -= flow;
        capacity[start][parent[start]] += flow;
    }
}

int edmonds_karp(
        const int source,
        const int sink,
        const vector<vector<int>>& G, 
        vector<vector<int>>& capacity) {
    vector<int> parent(G.size());
    int flow = 0;
    
    while (true) {
        // find augmenting paths
        bfs(source, parent, capacity, G);
        // if there are no more paths which reach the sink
        if (parent[sink] == -1) break;
        
        // check all augmenting paths which end at a neighbour of the sink
        for (int u : G[sink]) if (capacity[u][sink]) {
            int f = findMaxFlow(u, parent, capacity);    
            if (f == 0) continue;
            
            // augment the flow
            f = min(f, capacity[u][sink]);
            capacity[u][sink] -= f;
            capacity[sink][u] += f;
            augmentFlow(u, f, parent, capacity);
            
            flow += f;
        }
    }
    
    return flow;
}

int main() {
    ifstream fin("maxflow.in");
    ofstream fout("maxflow.out");
    
    int n, m; fin >> n >> m;
    
    vector<vector<int>> G(n), capacity(n, vector<int>(n, 0));
    
    for (int u, v, c; m; --m) {
        fin >> u >> v >> c;
        u--; v--;
        capacity[u][v] = c;
        G[u].push_back(v);
        G[v].push_back(u);
    }
    
    fout << edmonds_karp(0, G.size() - 1, G, capacity) << endl;
    
    return 0;
}