Cod sursa(job #2695946)

Utilizator killerdonuts358nicolae tudor killerdonuts358 Data 14 ianuarie 2021 22:16:55
Problema Flux maxim Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.04 kb
#include <fstream>
#include <iostream>
#include <vector>
#include <queue>
#include <limits>

using namespace std;

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

struct Edge {
    unsigned int to; // nod dest (from e index in lst adiacenta)
    int flow; // cat are in ea
    int cap; // cat poate tine
    unsigned int rev; // index muchie inversa in lst adiacenta
};

struct Node {
    vector<Edge> edges;
    int edgeCnt = 0;
    int level;
    void addEdge(unsigned int to, int cap, unsigned int rev) {
        edges.push_back({to, 0, cap, rev});
        ++edgeCnt;
    }
};

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

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

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

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

    bool BFS(unsigned int source, unsigned int target) {
        for (int i = 1; i <= nodeCnt; i++)
            nodes[i].level = -1;

        nodes[source].level = 0;

        queue<int> q;
        q.push(source);

        while (!q.empty()) {
            int from = q.front();
            q.pop();

            for (auto &edge:nodes[from].edges) {
                if (nodes[edge.to].level < 0 && edge.flow < edge.cap) {
                    nodes[edge.to].level = nodes[from].level + 1;

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

        return nodes[target].level > 0;
    }

    int DFS(unsigned int from, int flow, unsigned int target, int *visCount) {
        if (from == target)
            return flow;

        while (visCount[from] < nodes[from].edgeCnt) {
            Edge &adj = nodes[from].edges[visCount[from]];
            if (nodes[adj.to].level == nodes[from].level + 1 && adj.flow < adj.cap) {
                int currFlow = min(flow, adj.cap - adj.flow);
                int tempFlow = DFS(adj.to, currFlow, target, visCount);
                if (tempFlow > 0) {
                    adj.flow += tempFlow;
                    nodes[adj.to].edges[adj.rev].flow -= tempFlow;
                    return tempFlow;
                }
            }
            visCount[from]++;
        }
        return 0;
    }

    int maxFlow(unsigned int source, unsigned int target) {
        if (source == target)
            return -1;

        int total = 0;

        int *visCount = new int[nodeCnt + 1];
        while (BFS(source, target)) {
            fill(visCount, visCount + nodeCnt + 1, 0);
            while (int flow = DFS(source, INT_MAX, target, visCount))
                total += flow;
        }
        delete[] visCount;
        return total;
    }
};

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

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