Cod sursa(job #2838830)

Utilizator CraniXortDumitrescul Eduard CraniXort Data 24 ianuarie 2022 18:22:42
Problema Flux maxim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.73 kb
#include <bits/stdc++.h>

std::ifstream fin("maxflow.in");
std::ofstream fout("maxflow.out");

struct FlowEdge {
    int node, next;
    long long cap, flow = 0;
    FlowEdge(int node, int next, long long cap): node(node), next(next), cap(cap) {};
};

class Dinic {
    int V, E = 0, source, sink;
    std::vector <FlowEdge> edges;
    std::vector <std::vector <int>> adj;
    std::vector <int> level, start;

    public:

    Dinic(int V, int source, int sink): V(V), source(source), sink(sink) {
        adj.resize(V);
        level.resize(V);
        start.resize(V);
    }

    void addEdge(int src, int dest, int cap) {
        edges.push_back(FlowEdge(src, dest, cap));
        edges.push_back(FlowEdge(dest, src, 0));
        adj[src].push_back(E);
        adj[dest].push_back(E+1);
        E += 2;
    }

    std::queue <int> q;

    bool bfs() {
        std::fill(level.begin(), level.end(), -1);
        level[source] = 0;
        q.push(source);

        while(q.empty() == false) {
            int node = q.front();
            q.pop();

            for(int i = 0; i < adj[node].size(); i ++) {
                int next = edges[adj[node][i]].next;
                long long potential = edges[adj[node][i]].cap - edges[adj[node][i]].flow;
                if(level[next] != -1 or potential < 1)
                    continue;
                
                level[next] = level[node] + 1;
                q.push(next);
            }
        }

        return (level[sink] != -1);
    }

    long long dfs(int node, long long flow) {
        if(flow == 0)
            return 0;
        if(node == sink)
            return flow;

        for(int &i = start[node]; i < adj[node].size(); i ++) {
            int next = edges[adj[node][i]].next;
            long long potential = edges[adj[node][i]].cap - edges[adj[node][i]].flow;

            if(level[next] != level[node] + 1 or potential < 1)
                continue;

            long long nextFlow = dfs(next, std::min(flow, potential));
            if(nextFlow == 0)
                continue;

            edges[adj[node][i]].flow += nextFlow;
            edges[adj[node][i] ^ 1].flow -= nextFlow;
            return nextFlow;
        }
        return 0;
    }   

    long long maxFlow() {
        long long flow = 0;
        while(true) {
            if(bfs() == false)
                break;
            std::fill(start.begin(), start.end(), 0);
            while(long long f = dfs(source, 1e18))
                flow += f;
        }   
        return flow;
    }   
};



int main() {
    int V, E;
    fin >> V >> E;
    Dinic graph(V, 0, V-1);

    for(int i = 0, src, dest, cap; i < E; i ++) {
        fin >> src >> dest >> cap;
        graph.addEdge(src-1, dest-1, cap);
    }

    fout << graph.maxFlow();

    return 0;
}