Cod sursa(job #1893932)

Utilizator StarGold2Emanuel Nrx StarGold2 Data 26 februarie 2017 11:31:06
Problema Flux maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.6 kb
#include <bits/stdc++.h>
using namespace std;

const int DIM = 355;
const int INF = 0x3f3f3f3f;

int dp[DIM], fth[DIM], dst[DIM], aux[DIM];
int cap[DIM][DIM], cst[DIM][DIM];

bitset<DIM> mrk; vector<int> edg[DIM]; deque<int> que;
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> prq;

inline bool bf( int s, int d, int n ) {
    memset( dst, 0x3f, sizeof( dst ) );
    
    dst[s] = 0; mrk.reset(); mrk[s] = 1;
    for( que.push_back( s ); que.empty() == false; que.pop_front() ) {
        int x = que.front(); mrk[x] = false;
        
        for( int y : edg[x] ) {
            if( cap[x][y] != 0 && dst[y] > dst[x] + cst[x][y] ) {
                dst[y] = dst[x] + cst[x][y]; fth[y] = x;
            
                if( y != d && mrk[y] == false ) {
                    mrk[y] = true;
                    que.push_back( y );
                }
            }
        }
    }
    
    return ( dst[d] != INF );
}

inline bool dj( int s, int d, int n ) {
    memset(  dp, 0x3f, sizeof(  dp ) );
    memset( aux, 0x3f, sizeof( aux ) );
    
    dp[s] = aux[s] = 0;
    for( prq.push( make_pair( 0, s ) ); prq.empty() == false; ) {
        pair<int, int> x = prq.top(); prq.pop();
        
        if( dp[x.second] != x.first )
            continue;
        
        for( int y : edg[x.second] ) {
            if( cap[x.second][y] != 0 && dp[y] > dp[x.second] + dst[x.second] - dst[y] + cst[x.second][y] ) {
                dp[y] = dp[x.second] + dst[x.second] - dst[y] + cst[x.second][y];
                aux[y] = aux[x.second] + cst[x.second][y]; fth[y] = x.second;
                
                if( y != d )
                    prq.push( make_pair( dp[y], y ) );
            }
        }
    }
    
    memcpy( dst, aux, sizeof( aux ) );
    return ( dp[d] != INF );
}

int main( void ) {
    
    freopen( "fmcm.in" , "r", stdin  );
    freopen( "fmcm.out", "w", stdout );
    
    int n, m, s, d;
    scanf( "%d %d %d %d", &n, &m, &s, &d );
    
    for( int i = 1; i <= m; i ++ ) {
        int x, y, c, z;
        scanf( "%d %d %d %d", &x, &y, &c, &z );
        
        cap[x][y] = c; cst[x][y] =  z;
        cap[y][x] = 0; cst[y][x] = -z;
        edg[x].push_back( y );
        edg[y].push_back( x );
    }
    
    bf( s, d, n );
    
    int cmn = 0;
    while( dj( s, d, n ) ) {
        int mnm = INF;
        
        for( int i = d; i != s; i = fth[i] )
            mnm = min( mnm, cap[fth[i]][i] );
        
        cmn += dst[d] * mnm;
        for( int i = d; i != s; i = fth[i] ) {
            cap[fth[i]][i] -= mnm;
            cap[i][fth[i]] += mnm;
        }
    }
    
    printf( "%d\n", cmn );
    return 0;
}