Cod sursa(job #3215438)

Utilizator adiadi11Adrian Ariton adiadi11 Data 14 martie 2024 22:59:53
Problema Flux maxim Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.89 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:
    int source;
    int dest;
    int cap;
    int flow;
    int type;
    Edge *reverse;
    Edge(){
        type = 0;
        source = 0;
        dest = 0;
        cap = 0;
        flow = 0;
    }
    Edge(int t=0) : type(t) {
        source = 0;
        dest = 0;
        cap = 0;
        flow = 0;
    }
    void point(Edge *rev) {
        this->reverse = rev;
    }
    Edge(int s, int d, int c, int t = 0) : source(s), dest(d), cap(c), flow(0), type(t) {}

};

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

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

        graph.reserve(n + 1);
        for (int i = 0 ; i < e; ++i) {
            int 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);
        }
    }

    int max_flow(int source, int dest) {

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

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

            int flow = 100000001;
            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;
            }
        }

        int 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);
}