Cod sursa(job #1465429)

Utilizator mouse_wirelessMouse Wireless mouse_wireless Data 27 iulie 2015 12:57:40
Problema Flux maxim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.88 kb
#include <cstdio>
#include <cassert>
#include <algorithm>
#include <vector>
#include <list>
#include <queue>
#include <cstdlib>
#include <cstring>
using namespace std;
#define _submit
#ifdef _submit
#define InFile "maxflow.in"
#define OtFile "maxflow.out"
#else
#define InFile "fis.in"
#define OtFile "fis.out"
#endif
  
class edge {
private:
    int toNod, flow, capacity, ID;
    edge* dup;
    edge(int n1, int n2, int cap, int nr) {
        toNod = n2;
        capacity = cap;
        flow = 0;
        ID = nr;
    }
    void assignDup(edge *E) {
        dup = E;
    }
    friend class graph;
};
 
class graph {
private:
    vector< list<edge> > adiac;
    int edgeCounter;
public:
    graph(int nrNod) {
        adiac.resize(nrNod);
        edgeCounter = 0;
    }
    void newEdge(int n1, int n2, int cap) {
        adiac[n1].push_back(edge(n1, n2, cap, edgeCounter));
        adiac[n2].push_back(edge(n2, n1, 0, edgeCounter));
        adiac[n1].back().assignDup(&adiac[n2].back());
        adiac[n2].back().assignDup(&adiac[n1].back());
        edgeCounter++;
    }
    int sendFlows(vector<int>& parent, vector<int>& capToParent, vector<int*>& flowToParent, vector<int*>& flowToParentDup, queue<int>& Q) {
        while (!Q.empty())
            Q.pop();
        int endNod = adiac.size() - 1;
        int s = 0;
        memset(&parent[0], 0xFF, parent.size() * sizeof(parent[0]));
        Q.push(0);
        parent[0] = -2;
        while (!Q.empty()) {
            int t = Q.front();
            Q.pop();
            for (auto i = adiac[t].begin(); i != adiac[t].end(); ++i) {
                if (parent[i->toNod] != -1 || i->capacity - i->flow == 0)
                    continue;
                if (i->toNod == endNod) {
                    int M = i->capacity - i->flow;
                    int curNod = t;
                    while (parent[curNod] != -2) {
                        int availableFlow = capToParent[curNod] - *flowToParent[curNod];
                        if (!availableFlow)
                            break;
                        if (availableFlow < M)
                            M = availableFlow;
                        curNod = parent[curNod];
                    }
                    if (parent[curNod] != -2)
                        continue;
 
                    i->flow += M;
                    i->dup->flow -= M;
                    curNod = t;
                    while (parent[curNod] != -2) {
                        *flowToParent[curNod] += M;
                        *flowToParentDup[curNod] -= M;
                        curNod = parent[curNod];
                    }
                    s += M;
                }
                else {
                    int curNod = i->toNod;
                    parent[curNod] = t;
                    capToParent[curNod] = i->capacity;
                    flowToParent[curNod] = &i->flow;
                    flowToParentDup[curNod] = &i->dup->flow;
                    Q.push(curNod);
                }
            }
        }
        return s;
    }
    int EdmondsKarp() {
        int s = 0;
        vector<int> parent(adiac.size());
        vector<int> capToParent(adiac.size());
        vector<int*> flowToParent(adiac.size());
        vector<int*> flowToParentDup(adiac.size());
        queue<int> Q;
        while (true) {
            int res = sendFlows(parent, capToParent, flowToParent, flowToParentDup, Q);
            if (!res)
                break;
            s += res;
        }
        return s;
    }
};
 
int main() {
    assert(freopen(InFile, "r", stdin));
    assert(freopen(OtFile, "w", stdout));
    int N, M;
    scanf("%d%d", &N, &M);
    graph G(N);
    for (int i = 0; i < M; i++) {
        int a, b, c;
        scanf("%d%d%d", &a, &b, &c);
        G.newEdge(a - 1, b - 1, c);
    }
    printf("%d\n", G.EdmondsKarp());
}