Cod sursa(job #2422016)

Utilizator preda.andreiPreda Andrei preda.andrei Data 16 mai 2019 21:44:58
Problema Flux maxim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.52 kb
#include <fstream>
#include <queue>
#include <vector>

using namespace std;

class Graph
{
public:
    Graph(int nodes) : edges_(nodes), costs_(nodes, vector<int>(nodes, 0)) {}

    size_t Size() const { return edges_.size(); }

    void AddEdge(int a, int b, int cost)
    {
        edges_[a].push_back(b);
        edges_[b].push_back(a);
        costs_[a][b] = cost;
    }

    const vector<int>& Edges(int node) const
    {
        return edges_[node];
    }

    const int& Cost(int a, int b) const
    {
        return costs_[a][b];
    }

    int& Cost(int a, int b)
    {
        return costs_[a][b];
    }

private:
    vector<vector<int>> edges_;
    vector<vector<int>> costs_;
};

bool Bfs(const Graph &g, int source, int dest, vector<int> &pred)
{
    pred.assign(g.Size(), -1);

    queue<int> q;
    q.push(source);

    vector<bool> visited(g.Size(), false);
    visited[source] = true;

    while (!q.empty()) {
        auto node = q.front();
        q.pop();

        for (const auto &next : g.Edges(node)) {
            if (g.Cost(node, next) > 0 && !visited[next]) {
                visited[next] = true;
                pred[next] = node;
                q.push(next);
            }
        }
    }
    return visited[dest];
}

int FindMinCapacity(Graph &g, int node, int prev, const vector<int> &pred)
{
    auto res = g.Cost(node, prev);

    while (node != -1) {
        res = min(res, g.Cost(node, prev));
        prev = node;
        node = pred[node];
    }
    return res;
}

int Flow(Graph &g, int node, int prev, const vector<int> &pred)
{
    auto capacity = FindMinCapacity(g, node, prev, pred);
    if (capacity <= 0) {
        return 0;
    }

    while (node != -1) {
        g.Cost(node, prev) -= capacity;
        g.Cost(prev, node) += capacity;

        prev = node;
        node = pred[node];
    }
    return capacity;
}

int FindMaxFlow(Graph &g, int source, int dest)
{
    vector<int> pred;
    int max_flow = 0;

    while (Bfs(g, source, dest, pred)) {
        for (size_t i = 0; i < g.Size(); i += 1) {
            if (g.Cost(i, dest) > 0) {
                max_flow += Flow(g, i, dest, pred);
            }
        }
    }
    return max_flow;
}

int main()
{
    ifstream fin("maxflow.in");
    ofstream fout("maxflow.out");

    int nodes, edges;
    fin >> nodes >> edges;

    Graph graph(nodes);
    for (auto i = 0; i < edges; i += 1) {
        int a, b, cap;
        fin >> a >> b >> cap;
        graph.AddEdge(a - 1, b - 1, cap);
    }

    auto res = FindMaxFlow(graph, 0, nodes - 1);
    fout << res << "\n";

    return 0;
}