Cod sursa(job #1893914)

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

fstream in ( "fmcm.in" , ios::in  );
fstream out( "fmcm.out", ios::out );

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

int dp[DIM], fth[DIM], dst[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;

bool bf( int s, int d, int n ) {
    fill( dst + 1, dst + n + 1, INF );
    bool ok = false;
    
    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] && dst[y] > dst[x] + cst[x][y] ) {
                dst[y] = dst[x] + cst[x][y]; fth[y] = x;
            
                if( mrk[y] == false ) {
                    if( y != d ) {
                        que.push_back( y );
                        mrk[y] = true;
                    }
                    else
                        ok = true;
                }
            }
        }
    }
    
    return ok;
}

bool dj( int s, int d, int n ) {
    fill( dp + 1, dp + n + 1, INF ); bool ok = false;
    
    dp[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;
        
        if( x.second == d )
            break;
        
        for( int y : edg[x.second] ) {
            if( cap[x.second][y] && 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]; fth[y] = x.second;
                
                if( y != d )
                    prq.push( make_pair( dp[y], y ) );
                else
                    ok = true;
            }
        }
    }
    
    return ok;
}

int main( void ) {
    ios::sync_with_stdio( false );
    
    int n, m, s, d;
    in >> n >> m >> s >> d;
    
    for( int i = 1; i <= m; i ++ ) {
        int x, y, c, z;
        in >> 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] );
        
        if( mnm == 0 )
            continue;
        
        for( int i = d; i != s; i = fth[i] ) {
            cmn += cst[fth[i]][i] * mnm;
            
            cap[fth[i]][i] -= mnm;
            cap[i][fth[i]] += mnm;
        }
    }
    
    out << cmn << endl;
    return 0;
}