Cod sursa(job #3215444)

Utilizator adiadi11Adrian Ariton adiadi11 Data 14 martie 2024 23:08:25
Problema Flux maxim Scor 60
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3 kb
#include <iostream>
#include <fstream>

#include <vector>
#include <queue>
#define REVERSE 1
#define NORMAL 0
std::ifstream fin("maxflow.in");
std::ofstream fout("maxflow.out");
class Edge {
public:
    long long source;
    long long dest;
    long long cap;
    long long flow;
    long long type;
    Edge *reverse;
    Edge(){
        type = 0;
        source = 0;
        dest = 0;
        cap = 0;
        flow = 0;
    }
    Edge(long long t=0) : type(t) {
        source = 0;
        dest = 0;
        cap = 0;
        flow = 0;
    }
    void point(Edge *rev) {
        this->reverse = rev;
    }
    Edge(long long s, long long d, long long c, long long t = 0) : source(s), dest(d), cap(c), flow(0), type(t) {}

};

class Graph {
public:
    long long nodes;
    std::vector< std::vector<Edge *> > graph;
    std::vector<Edge *> all_edges;
    std::vector<Edge *> all_revedges;

    void read(std::istream & inp = std::cin) {
        long long n, e;
        inp >> n >> e;
        nodes = n;

        graph.reserve(n + 1);
        for (long long i = 0 ; i < e; ++i) {
            long long s, d, c;
            inp >> s >> d >> c;
            Edge *e1 = new Edge(s, d, c);
            Edge *e2 = new Edge(d, s, -c, REVERSE);
            e1->point(e2);
            e2->point(e1);
            graph[s].push_back(e1);
            graph[d].push_back(e2);
            all_edges.push_back(e1);
            all_revedges.push_back(e2);
        }
    }

    long long max_flow(long long source, long long dest) {

        while (1) {
            // perform DFS
            std::queue<long long> q;
            q.push(source);
            std::vector<Edge *> predec(nodes + 1, 0);

            while(!q.empty() && predec[dest] == nullptr) {
                long long nod = q.front();
                q.pop();
                for (auto& edge : graph[nod]) {
                    if (predec[edge->dest] == nullptr && edge->cap > edge->flow) {
                        q.push(edge->dest);
                        predec[edge->dest] = edge;
                    }
                }
            }
            predec[source] = nullptr;
     
            if (predec[dest] == nullptr)
                break;

            long long flow = 110001;
            for (Edge *edge = predec[dest]; edge != nullptr; edge = predec[edge->source]) {
                flow = std::min(flow, edge->cap - edge->flow);
            }
            if (flow == 0)
                break;
            for (Edge *edge = predec[dest]; edge != nullptr; edge = predec[edge->source]) {
                edge->flow = edge->flow + flow;
                edge->reverse->flow = edge->reverse->flow - flow;
            }
        }

        long long x = 0;
        for (auto ed : graph[source]) {
            x += ed->flow;
        }
        // for (auto ed : all_edges) {
        //     std::cout << (ed->source) << " " << (ed->dest) << " flow: "<< (ed->flow) << "/" << (ed->cap) <<"\n";
        // }
        return x;
    }
};

int main() {
    Graph g;
    g.read(fin);
    fout << g.max_flow(1, g.nodes) << "\n";
}