Cod sursa(job #1250998)

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

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

inline int findResidualCapacity(
        int start,
        const vector<int>& bfsTree,
        const vector<vector<int>>& capacity) {
    int residualCapacity = numeric_limits<int>::max();

    for (; start != bfsTree[start] && residualCapacity; start = bfsTree[start])
        residualCapacity = min(residualCapacity, capacity[bfsTree[start]][start]);
    
    return residualCapacity;
}

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

int edmonds_karp(
        const int source,
        const int sink,
        const vector<vector<int>>& G, 
        vector<vector<int>>& capacity) {
    vector<int> bfsTree(G.size());
    int flow = 0;
    
    while (true) {
        // find augmenting paths
        bfs(source, bfsTree, capacity, G);
        // if there are no more paths which reach the sink
        if (bfsTree[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 residualCapacity = findResidualCapacity(u, bfsTree, capacity);    
            if (residualCapacity == 0) continue;
            
            // augment the flow
            residualCapacity = min(residualCapacity, capacity[u][sink]);
            capacity[u][sink] -= residualCapacity;
            capacity[sink][u] += residualCapacity;
            augmentFlow(u, residualCapacity, bfsTree, capacity);
            
            flow += residualCapacity;
        }
    }
    
    return flow;
}

int main() {
    ifstream fin("maxflow.in");
    ofstream fout("maxflow.out");
    
    int n, m; fin >> n >> m;
    
    // these are actually the residual network and its capacity
    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;
}