Cod sursa(job #2696006)

Utilizator killerdonuttudor nicolae killerdonut Data 15 ianuarie 2021 01:05:44
Problema Flux maxim Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.86 kb
#include <fstream>
#include <vector>
#include <queue>

using namespace std;

#define INT_MAX       2147483647

ifstream fin("maxFlow.in");
ofstream fout("maxFlow.out");

struct Edge {
    int to, flow, cap, revEdgeId;
};

struct Node {
    vector<Edge> edges;
    int edgeCnt = 0;
    int level;

    void addEdge(int to, int cap, int rev) {
        edges.push_back({to, 0, cap, rev});
        ++edgeCnt;
    }
};

struct Graph {
    int nodeCnt, edgeCnt;
    int *level;
    vector<Node> nodes;

    Graph(int N, int M) {
        nodes.resize(N + 1);
        this->nodeCnt = N;
        this->edgeCnt = M;
        level = new int[N + 1];

        for (int i = 1, x, y, c; i <= edgeCnt; i++) {
            fin >> x >> y >> c;
            addEdge(x, y, c);
        }
    }

    void addEdge(int from, int to, int cap) {
        nodes[from].addEdge(to, cap, nodes[to].edgeCnt);
        nodes[to].addEdge(from, 0, nodes[from].edgeCnt - 1);
    }


    bool BFS(int s, int t) {
        /** Calculez nivelele nodurilor*/

        for (int i = 1; i <= nodeCnt; i++)
            level[i] = -1;

        level[s] = 0;

        queue<int> q;
        q.push(s);
        while (!q.empty()) {
            int from = q.front();
            q.pop();

            for (auto &nod:nodes[from].edges) {
                // daca nu am mai fost pe aici & muchia nu e saturata
                if (level[nod.to] < 0 && nod.flow < nod.cap) {
                    level[nod.to] = level[from] + 1;

                    q.push(nod.to);
                }
            }
        }

        return level[t] > 0;
    }

    int DFS(int from, int flow, int t, int *start) {
        if (from == t)
            return flow;

        //trec pe rand prin toate muchiile adiacentem

        // in start[from] tin nr muchii vizitate
        for (; start[from] < nodes[from].edgeCnt; start[from]++) {
            Edge &m = nodes[from].edges[start[from]];
            if (level[m.to] == level[from] + 1 && m.flow < m.cap) {
                int curr_flow = min(flow, m.cap - m.flow);
                int temp_flow = DFS(m.to, curr_flow, t, start);
                if (temp_flow > 0) {
                    m.flow += temp_flow;
                    nodes[m.to].edges[m.revEdgeId].flow -= temp_flow;
                    return temp_flow;
                }
            }
        }
        return 0;
    }

    int maxFlow(int s, int t) {
        if (s == t)
            return -1;

        int total = 0;

        int *start = new int[nodeCnt + 1];
        while (BFS(s, t)) {
            fill(start, start + nodeCnt + 1, 0);
            while (int flow = DFS(s, INT_MAX, t, start))
                total += flow;
        }
        return total;
    }
};

int main() {
    int n, m;
    fin >> n >> m;
    Graph gr(n, m);

    fout << gr.maxFlow(1, n);
}