Cod sursa(job #2289723)

Utilizator felixiPuscasu Felix felixi Data 25 noiembrie 2018 09:20:34
Problema Flux maxim Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.05 kb
#include <bits/stdc++.h>

using namespace std;

namespace SmartFlow
{
    const int NMAX = 1000;
    const int FMAX = (1 << 16);

    int N;
    vector<int> graph[NMAX+2];
    bool active[NMAX+2], viz[NMAX+2];
    int cap[NMAX+2][NMAX+2], flow[NMAX+2][NMAX+2];
    int source, destination;

    bool push(int nod, int where, int c)
    {
        viz[nod] = 1;
        if( nod == where )
            return 1;
        for( auto x : graph[nod] ) {
            if( active[x] && !viz[x] && flow[nod][x] + c <= cap[nod][x] && push(x, where, c) ) {
                flow[nod][x] += c;
                flow[x][nod] -= c;
                return 1;
            }
        }
        return 0;
    }

    bool pull(int nod, int where, int c)
    {
        viz[nod] = 1;
        if( nod == where )
            return 1;
        for( auto x : graph[nod] ) {
            if( active[x] && !viz[x] && flow[nod][x] >= c && pull(x, where, c) ) {
                flow[nod][x] -= c;
                flow[x][nod] += c;
                return 1;
            }
        }
        return 0;
    }

    void force_path(int nod, int where, int units, bool (*func)(int a, int b, int c))
    {
        int scos = 0, c = FMAX;
        while(c) {
            if( scos + c <= units && !(*func)(nod, where, c) )
                c /= 2;
        }
        assert(scos == units);
    }

    void enable(int nod)
    {
        active[nod] = 1;
    }

    void disable(int nod)
    {
        if( !active[nod] ) return ;
        active[nod] = 0;
        for( auto x : graph[nod] ) {
            if( flow[nod][x] > 0 )
                force_path(x, destination, flow[nod][x], pull);
            else if( flow[nod][x] < 0 )
                force_path(source, x, -flow[nod][x], push);

            flow[nod][x] = flow[x][nod] = 0;
        }
    }

    void activate_all()
    {
        for( int i = 1;  i <= N;  ++i )
            active[i] = 1;
    }

    void calc_flow()
    {
        int units = FMAX;
        while( units ) {
            memset(viz, 0, sizeof(viz));
            if( !push(source, destination, units) )
                units /= 2;
        }
    }

    int get_flow()
    {
        int ans = 0;
        int node = (graph[source].size() < graph[destination].size() ? source : destination);
        for( auto x : graph[node] )
            ans += abs(flow[(node == source ? source : x)][(node == source ? x : destination)]);
        return ans;
    }

    void push_edge(int x, int y, int c)
    {
        cap[x][y] += c;
        graph[x].push_back(y);
        graph[y].push_back(x);
    }
}

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

int main()
{
    int N, M;
    in >> N >> M;
    SmartFlow::N = N;
    SmartFlow::source = 1;
    SmartFlow::destination = N;
    SmartFlow::activate_all();
    for( int i = 1;  i <= M;  ++i ) {
        int x,y,c;
        in >> x >> y >> c;
        SmartFlow::push_edge(x,y,c);
    }
    SmartFlow::calc_flow();
    out << SmartFlow::get_flow() << '\n';
    return 0;
}