Cod sursa(job #414972)

Utilizator al_flAlexandru Flavian al_fl Data 10 martie 2010 19:32:54
Problema Flux maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.98 kb
#include <algorithm>
#include <bitset>
#include <queue>
#include <vector>

using namespace std;

#define INF 0x3f3f3f3f
#define MAX_N 355
#define MAX_S 10005

typedef short int int_16;
typedef int int_32;

char s[ MAX_S ];
int_16 N, M, S, D;
int_16 cnt_s, t[ MAX_N ], cap[ MAX_N ][ MAX_N ], flx[ MAX_N ][ MAX_N ];
int_32 cst_min, c[ MAX_N ];
bitset <MAX_N> f;
vector < pair <int_16, int_16> > v[ MAX_N ];

struct cmp {

    bool operator()( const int_16 &x, const int_16 &y ) {

        return c[ x ] > c[ y ];
    }
};
priority_queue < int_16, vector <int_16>, cmp > h;

int_32 bellman_ford() {

    int_16 nod;
    int_32 f_min;
    vector < pair <int_16, int_16> > :: iterator it;

    f.reset();
    memset( c, INF, sizeof( c ) );
    memset( t, 0, sizeof( t ) );

    h.push( S );
    c[ S ] = 0;
    f[ S ] = true;

    while( !h.empty() ) {

        nod = h.top();
        h.pop();
        f[ nod ] = false;

        for( it = v[ nod ].begin(); it != v[ nod ].end(); ++it )
            if( cap[ nod ][ it->first ] - flx[ nod ][ it->first ] > 0 && c[ nod ] + it->second < c[ it->first ] ) {

                c[ it->first ] = c[ nod ] + it->second;
                t[ it->first ] = nod;

                if( f[ it->first ] == false ) {

                    h.push( it->first );
                    f[ it->first ] = true;
                }
            }
    }

    if( c[ D ] != INF ) {

        f_min = INF;
        for( nod = D; nod != S; nod = t[ nod ] )
            f_min = min( f_min, cap[ t[ nod ] ][ nod ] - flx[ t[ nod ] ][ nod ] );

        if( f_min != INF ) {

            for( nod = D; nod != S; nod = t[ nod ] ) {

                flx[ t[ nod ] ][ nod ] += f_min;
                flx[ nod ][ t[ nod ] ] -= f_min;
            }

            return f_min * c[ D ];
        }
    }

    return 0;
}

void read( int_16 &val ) {

    int_16 sgn;

    sgn = 1;
    while( !isdigit( s[ cnt_s ] ) ) {

        if( s[ cnt_s ] == '-')
            sgn = -1;
        if( ++cnt_s == MAX_S ) {

            fread( s, 1, MAX_S, stdin );
            cnt_s = 0;
        }
    }

    val = 0;
    while( isdigit( s[ cnt_s ] ) ) {

        val = val * 10 + s[ cnt_s ] - '0';
        if( ++cnt_s == MAX_S ) {

            fread( s, 1, MAX_S, stdin );
            cnt_s = 0;
        }
    }

    val *= sgn;
}

int main() {

    freopen( "fmcm.in", "r", stdin );
    freopen( "fmcm.out", "w", stdout );

    int_16 x, y, cpc, cst;
    int_32 ok;

    cnt_s = MAX_S - 1;

    read( N );
    read( M );
    read( S );
    read( D );

    while( M-- ) {

        read( x );
        read( y );
        read( cpc );
        read( cst );

        v[ x ].push_back( make_pair( y, cst ) );
        v[ y ].push_back( make_pair( x, -cst ) );
        cap[ x ][ y ] = cpc;
    }

    do {

        ok = bellman_ford();
        cst_min += ok;
    }
    while( ok );

    printf( "%d", cst_min );

    return 0;
}