Cod sursa(job #943644)

Utilizator freak93Adrian Budau freak93 Data 26 aprilie 2013 00:26:23
Problema Flux maxim Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 4.18 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <limits>

using namespace std;

class Graph {
  public:
    explicit Graph(const int &size):
            size_(size),
            edges_(size),
            capacity_(size, vector<int>(size, 0)),
            flow_(size, vector<int>(size, 0)) {
    }

    void addEdge(const int &from, const int &to, int flow) {
        edges_[from].push_back(to);
        edges_[to].push_back(from);
        capacity_[from][to] = flow;
    }

    int maxFlow(const int &source, const int &sink) {
        int max_flow = 0;
        do {
            vector<int> level(size_, -1);
            level[source] = 0;

            vector< vector<int> > level_graph = levelGraph(source, sink);

            int flow = 0;
            do {
                vector<int> path(size_, -1);
                path[source] = source;
                dfsLevelGraph(source, level_graph, path);
                if (path[sink] == -1)
                    break;

                for (vector<int>::iterator from = level_graph[sink].begin(); from != level_graph[sink].end(); ++from) {
                    int to_add = numeric_limits<int>::max();
                    path[sink] = *from;
                    for (int node = sink; node != source; node = path[node]) {
                        if (path[node] == -1) {
                            to_add = 0;
                            break;
                        }

                        to_add = min(to_add, capacity_[path[node]][node] - flow_[path[node]][node]);
                        if (not to_add) {
                            path[node] = -1;
                            break;
                        }
                    }

                    if (not to_add) {
                        for (int node = sink, aux; node != -1; node = aux) {
                            aux = path[node];
                            path[node] = -1;
                        }
                        continue;
                    }

                    flow += to_add;
                    for (int node = sink; node != source; node = path[node]) {
                        flow_[path[node]][node] += to_add;
                        flow_[node][path[node]] -= to_add;
                    }
                }
            } while (true);

            if (flow == 0)
                break;
            max_flow += flow;
        } while (true);
        return max_flow;
    }

  private:
    vector< vector<int> > levelGraph(const int &source, const int &sink) {
        queue<int> Q;
        vector<int> level(size_, -1);

        Q.push(source);
        level[source] = 0;

        vector< vector<int> > result(size_);
        while (!Q.empty()) {
            int node = Q.front();
            Q.pop();

            if (node == sink)
                continue;
            for (vector<int>::iterator it = edges_[node].begin(); it != edges_[node].end(); ++it)
                if (level[*it] == -1 && flow_[node][*it] < capacity_[node][*it]) {
                    level[*it] = level[node] + 1;
                    Q.push(*it);
                    result[node].push_back(*it);
                    if (*it == sink)
                        result[*it].push_back(node);
                } else if (level[*it] == level[node] + 1) {
                    result[node].push_back(*it);
                    if (*it == sink)
                        result[*it].push_back(node);
                }
        }

        return result;
    }

    void dfsLevelGraph(const int &node, const vector< vector<int> > &edges, vector<int> &path) {
        for (vector<int>::const_iterator it = edges[node].begin(); it != edges[node].end(); ++it)
            if (flow_[node][*it] < capacity_[node][*it] && path[*it] == -1) {
                path[*it] = node;
                dfsLevelGraph(*it, edges, path);
            }
    }

    int size_;
    vector< vector<int> > edges_;
    vector< vector<int> > capacity_;
    vector< vector<int> > flow_;
};

int main() {
    ifstream cin("maxflow.in");
    ofstream cout("maxflow.out");

    int N, M; cin >> N >> M;

    Graph G(N);
    for (int i = 0; i < M; ++i) {
        int x, y, z; cin >> x >> y >> z;
        G.addEdge(x - 1, y - 1, z);
    }

    cout << G.maxFlow(0, N - 1) << "\n";
}