Cod sursa(job #2659176)

Utilizator Alex_tz307Lorintz Alexandru Alex_tz307 Data 15 octombrie 2020 23:43:55
Problema Flux maxim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.11 kb
#include <bits/stdc++.h>

using namespace std;

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

typedef long long int64;

class FlowEdge {
    public:
        int u, v;
        int64 capacity, flow = 0;

        FlowEdge(int u, int v, int64 capacity) {
            this -> u = u;
            this -> v = v;
            this -> capacity = capacity;
        }
};

class Dinic {
    public:
        const int64 INF = 1e18L;
        vector < FlowEdge > edges;
        vector < vector < int > > adj;
        int N, M = 0, source, sink;
        vector < int > level, ptr;
        queue < int > Q;

        Dinic(int N, int source, int sink) {
            this -> N = N;
            this -> source = source;
            this -> sink = sink;
            adj.resize(N + 1);
            level.resize(N + 1);
            ptr.resize(N + 1);
        }

        void add_edge(int u, int v, int64 capacity) {
            edges.emplace_back(u, v, capacity);
            edges.emplace_back(v, u, 0);
            adj[u].emplace_back(M++);
            adj[v].emplace_back(M++);
        }

        bool BFS() {
            while(!Q.empty()) {
                int curr = Q.front();
                Q.pop();
                for(int id : adj[curr])
                    if(level[edges[id].v] == -1 && edges[id].capacity > edges[id].flow) {
                        level[edges[id].v] = level[curr] + 1;
                        Q.emplace(edges[id].v);
                    }
            }
            return level[sink] != -1;
        }

        int64 DFS(int u, int64 pushed) {
            if(pushed == 0)
                return 0;
            if(u == sink)
                return pushed;
            for(int& p = ptr[u]; p < (int)adj[u].size(); ++p) {
                int id = adj[u][p],
                    v = edges[id].v;
                if(level[u] + 1 != level[v] || edges[id].capacity <= edges[id].flow)
                    continue;
                int64 new_flow = DFS(v, min(pushed, edges[id].capacity - edges[id].flow));
                if(new_flow == 0)
                    continue;
                edges[id].flow += new_flow;
                edges[id ^ 1].flow -= new_flow;
                return new_flow;
            }
            return 0;
        }

        int64 max_flow() {
            int64 flow_max = 0;
            while(true) {
                fill(level.begin(), level.end(), -1);
                level[source] = 0;
                Q.emplace(source);
                if(!BFS())
                    break;
                fill(ptr.begin(), ptr.end(), 0);
                while(int64 pushed = DFS(source, INF))
                    flow_max += pushed;
            }
            return flow_max;
        }
};

int main() {
    fin.sync_with_stdio(false);
    fout.sync_with_stdio(false);
    fin.tie(nullptr);
    fout.tie(nullptr);
    int N, M;
    fin >> N >> M;
    Dinic Graph(N, 1, N);
    while(M--) {
        int u, v;
        int64 capacity;
        fin >> u >> v >> capacity;
        Graph.add_edge(u, v, capacity);
    }
    fout << Graph.max_flow();
}