Cod sursa(job #1437310)

Utilizator crucerucalinCalin-Cristian Cruceru crucerucalin Data 17 mai 2015 14:31:09
Problema Flux maxim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.26 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <limits>
#include <algorithm>

using FlowGraph = std::vector<std::vector<int>>;
using IntTable = std::vector<std::vector<int>>;

const int NONE = -1;

std::vector<int>
bfsTree(
        const FlowGraph &graph,
        const IntTable &capacity,
        int source,
        int sink
)
{
    std::vector<int> parent(graph.size(), NONE);
    std::queue<int> bfsQueue;

    bfsQueue.emplace(source);
    while (!bfsQueue.empty()) {
        auto u = bfsQueue.front();

        bfsQueue.pop();
        for (auto &v : graph[u])
            if (v != sink && capacity[u][v] > 0 && parent[v] == NONE) {
                parent[v] = u;
                bfsQueue.emplace(v);
            }
    }

    return parent;
}

int
maxFlow(
        const FlowGraph &graph,
        IntTable &capacity,
        int source,
        int sink
)
{
    auto maxFlow = 0;

    while (true) {
        auto parentTree = bfsTree(graph, capacity, source, sink);
        auto newFlow = maxFlow;

        for (auto &u : graph[sink]) {
            if (!capacity[u][sink] || parentTree[u] == NONE)
                continue;

            auto v = u;
            auto w = sink;
            auto min = std::numeric_limits<int>::max();

            while (w != source) {
                min = std::min(min, capacity[v][w]);
                w = v;
                v = parentTree[v];
            };

            newFlow += min;

            v = u;
            w = sink;
            while (w != source) {
                capacity[v][w] -= min;
                capacity[w][v] += min;
                w = v;
                v = parentTree[v];
            }
        }

        if (newFlow == maxFlow)
            break;
        else
            maxFlow = newFlow;
    }

    return maxFlow;
}

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

    int N, M;

    fin >> N >> M;
    FlowGraph graph(N);
    IntTable capacity(N, std::vector<int>(N, 0));

    for (auto i = 0; i < M; ++i) {
        int x, y, c;

        fin >> x >> y >> c;
        capacity[x - 1][y - 1] = c;
        graph[x - 1].emplace_back(y - 1);
        graph[y - 1].emplace_back(x - 1);
    }

    fout << maxFlow(graph, capacity, 0, N - 1) << std::endl;

    return 0;
}