Cod sursa(job #2403927)

Utilizator felixiPuscasu Felix felixi Data 12 aprilie 2019 08:10:40
Problema Flux maxim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.12 kb
#include <bits/stdc++.h>

using namespace std;

struct DinicFlow
{
    struct Edge
    {
        int to, flow, next;
    };

    vector<int> adia, at, h;
    vector<Edge> edges;
    int S, D;

    DinicFlow(int n, int s, int d) : adia(n + 1, -1), h(n + 1, -1), S(s), D(d) {}

    void addEdge(int from, int to, int cap)
    {
        edges.push_back({to, cap, adia[from]});
        adia[from] = edges.size() - 1;
        edges.push_back({from, 0, adia[to]});
        adia[to] = edges.size() - 1;
    }

    int bfs()
    {
        vector<int> q = {S};
        fill(h.begin(), h.end(), -1);
        h[S] = 1;
        for( int it = 0;  it < q.size();  ++it ) {
            int nod = q[it];
            for( int i = adia[nod];  i != -1;  i = edges[i].next ) {
                int x = edges[i].to;
                if( edges[i].flow && h[x] == -1 ) {
                    h[x] = h[nod] + 1;
                    q.push_back(x);
                }
            }
        }
        return h[D] != -1;
    }

    int dfs(int nod, int cap)
    {
        if( nod == D || cap == 0 )
            return cap;

        while( at[nod] != -1 ) {
            Edge& e = edges[ at[nod] ];
            int d;
            if( e.flow && h[e.to] == 1 + h[nod] && (d = dfs(e.to, min(e.flow, cap))) ) {
                e.flow -= d;
                edges[ at[nod] ^ 1 ].flow += d;
                return d;
            }
            else
                at[nod] = edges[ at[nod] ].next;
        }
        return 0;
    }

    int getFlow()
    {
        int ans = 0;
        while(bfs()) {
            at = adia;
            int added = dfs(S, 1e9);
            while( added ) {
                ans += added;
                added = dfs(S, 1e9);
            }
        }
        return ans;
    }
};

int main()
{
    ifstream in("maxflow.in");
    ofstream out("maxflow.out");
    int N, M, S, D;
    in >> N >> M;
    DinicFlow DF(N, 1, N);
    for( int i = 1;  i <= M;  ++i ) {
        int a,b,c;
        in >> a >> b >> c;
        DF.addEdge(a, b, c);
    }
    out << DF.getFlow() << '\n';
    return 0;
}