Cod sursa(job #1160055)

Utilizator AlexandruValeanuAlexandru Valeanu AlexandruValeanu Data 30 martie 2014 10:28:29
Problema Flux maxim Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 3.42 kb
#include <iostream>
#include <fstream>
#include <cstring>

using namespace std;

class MaximumFlow
{
    const int inf = 1 << 30;

    public:

        MaximumFlow( const int n )
        {
            N = n;

            alloc_2d( C );
            alloc_2d( F );
            alloc_2d( G );

            alloc_1d( vis );
            alloc_1d( coada );
            alloc_1d( tata );
        }

        void addEdge( int x, int y, int c )
        {
            G[x][ ++G[x][0] ] = y;
            C[x][y] = c;
        }

        int flow( int S, int D )
        {
            return EdmondsKarp( S, D );
        }

    private:

        int N;
        int **C;
        int **F;
        int **G;
        int *vis;
        int *coada;
        int *tata;

        void alloc_1d( int *&x )
        {
            x = new int[N + 2];

            for ( int i = 0; i <= N + 1; ++i )
                    x[i] = 0;
        }

        void alloc_2d( int **&x )
        {
            x = new int*[N + 2];

            for ( int i = 0; i <= N; ++i )
                    x[i] = new int[N + 2];

            for ( int i = 0; i <= N; ++i )
                    for ( int j = 0; j <= N; ++j )
                            x[i][j] = 0;
        }

        inline bool BFS( int S, int D )
        {
            for ( int i = 0; i <= N; ++i )
                    vis[i] = 0;

            int st = 1, dr = 1;
            coada[1] = S;
            vis[S] = 1;

            while ( st <= dr )
            {
                int nod = coada[ st++ ];

                for ( int i = 1; i <= G[nod][0]; ++i )
                {
                    int vecin = G[nod][i];

                    if ( !vis[vecin] && C[nod][vecin] > F[nod][vecin] )
                    {
                        vis[vecin] = 1;
                        tata[vecin] = nod;
                        coada[ ++dr ] = vecin;

                        if ( vecin == D )
                                return true;
                    }
                }
            }

            return false;
        }

        int EdmondsKarp( int S, int D )
        {
            int flow = 0;
            int fmin, nod;

            while ( BFS( S, D ) )
            {
                for ( int i = 1; i <= G[D][0]; ++i )
                {
                    int vecin = G[D][i];

                    if ( !vis[vecin] || F[vecin][D] >= C[vecin][D] ) continue;

                    tata[D] = vecin;
                    fmin = inf;

                    for ( int nod = D; nod != S; nod = tata[nod] )
                            fmin = min( fmin, C[ tata[nod] ][nod] - F[ tata[nod] ][nod] );


                    if ( fmin == 0 ) continue;

                    for ( int nod = D; nod != S; nod = tata[nod] )
                    {
                        F[ tata[nod] ][nod] += fmin;
                        F[nod][ tata[nod] ] -= fmin;
                    }

                    flow += fmin;
                }
            }

            return flow;
        }
};

int N, M;

int main()
{
    ifstream f("maxflow.in");
    ofstream g("maxflow.out");

    f >> N >> M;

    MaximumFlow MF( N );

    for ( int i = 1, x, y, c; i <= M; ++i )
    {
        f >> x >> y >> c;

        MF.addEdge( x, y, c );
        MF.addEdge( y, x, 0 );
    }

    g << MF.flow( 1, N ) << "\n";

    f.close();
    g.close();

    return 0;
}