Cod sursa(job #1163615)

Utilizator a_h1926Heidelbacher Andrei a_h1926 Data 1 aprilie 2014 15:15:01
Problema Flux maxim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.56 kb
#include <fstream>
#include <vector>
#include <algorithm>
#include <queue>

using namespace std;

class Graph {
  public:
    static const int NIL = -1;
    static const int oo = 0x3f3f3f3f;

    class Edge {
      public:
        int from, to, capacity, flow;

        Edge(const int _from = NIL, const int _to = NIL, const int _capacity = 0):
          from(_from),
          to(_to),
          capacity(_capacity),
          flow(0) {}

        bool IsSaturated() const {
            return capacity == flow;
        }
    };

    Graph(const int _V = 0):
      V(_V),
      E(0),
      edges(vector<Edge>()),
      G(vector< vector<int> >(_V, vector<int>())) {}

    int Size() const {
        return V;
    }

    void AddEdge(const Edge &e) {
        edges.push_back(e);
        G[e.from].push_back(E++);
    }

    int MaximumFlow(const int source, const int sink) {
        InitializeNetwork();
        int maxFlow = 0;
        vector<int> father;
        while (BFS(source, sink, father)) {
            for (vector<int>::const_iterator e = G[sink].begin(); e != G[sink].end(); ++e) {
                if (edges[NonE(*e)].IsSaturated() || father[edges[*e].to] == NIL)
                    continue;
                father[sink] = NonE(*e);
                int flow = oo;
                for (int x = sink; x != source; x = edges[father[x]].from)
                    flow = min(flow, edges[father[x]].capacity - edges[father[x]].flow);
                for (int x = sink; x != source; x = edges[father[x]].from) {
                    edges[father[x]].flow += flow;
                    edges[NonE(father[x])].flow -= flow;
                }
                maxFlow += flow;
            }
        }
        ClearResidualNetwork();
        return maxFlow;
    }

  private:
    int V, E;
    vector<Edge> edges;
    vector< vector<int> > G;

    int NonE(const int e) const {
        if (e < E)
            return e + E;
        else
            return e - E;
    }

    void InitializeNetwork() {
        for (int e = 0; e < E; ++e) {
            edges[e].flow = 0;
            edges.push_back(Edge(edges[e].to, edges[e].from, 0));
            G[edges[e].to].push_back(NonE(e));
        }
    }

    bool BFS(const int source, const int destination, vector<int> &father) const {
        father = vector<int>(V, NIL);
        father[source] = 2 * E;
        queue<int> q;
        for (q.push(source); !q.empty(); q.pop()) {
            int x = q.front();
            if (x == destination)
                continue;
            for (vector<int>::const_iterator e = G[x].begin(); e != G[x].end(); ++e) {
                if (!edges[*e].IsSaturated() && father[edges[*e].to] == NIL) {
                    father[edges[*e].to] = *e;
                    q.push(edges[*e].to);
                }
            }
        }
        return father[destination] != NIL;
    }

    void ClearResidualNetwork() {
        for (; int(edges.size()) > E; edges.pop_back())
            G[edges.back().from].pop_back();
    }
};

Graph G;
int Answer;

void Solve() {
    Answer = G.MaximumFlow(0, G.Size() - 1);
}

void Read() {
    ifstream cin("maxflow.in");
    int v, e;
    cin >> v >> e;
    G = Graph(v);
    for (; e > 0; --e) {
        int x, y, c;
        cin >> x >> y >> c;
        G.AddEdge(Graph::Edge(x - 1, y - 1, c));
    }
    cin.close();
}

void Print() {
    ofstream cout("maxflow.out");
    cout << Answer << "\n";
    cout.close();
}

int main() {
    Read();
    Solve();
    Print();
    return 0;
}