Cod sursa(job #2386469)

Utilizator Andrei-27Arhire Andrei Andrei-27 Data 23 martie 2019 00:15:31
Problema Flux maxim de cost minim Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.78 kb
#include <bits/stdc++.h>
#define pb push_back
using namespace std ;
const int NR = 355 ;
const int oo = ( 1 << 30 ) ;
ifstream in ("fmcm.in") ;
ofstream out ("fmcm.out") ;
vector < int > v [ NR ] ;
int cap [ NR ][ NR ] , cost [ NR ][ NR ] ;
int dist [ NR ] , real_d [ NR ] , t [ NR ] ;
int n , m , c , z , x , y , s , d , flow , cst ;
int64_t ans ;
vector < int > :: iterator it ;
vector < int  > dis ( NR ) ;
bitset < NR > inq ;
struct cmp  {
    bool operator ()( pair < int , int > i , pair < int , int > j )   {
    return i.second > j.second ;
    }
};
priority_queue < int , vector < pair < int , int > > , cmp > qu ;
bool dijkstra ( )   {
    int nod , i , new_d ;
    for ( i = 1 ; i <= n ; ++ i )   dis [ i ] = oo ;
    real_d [ s ] = 0 ;
    dis [ s ] = 0 ;
    qu.push( { s , 0 } ) ;
    while ( !qu.empty() )   {
        nod = qu.top().first ;
        cst = qu.top().second ;
        qu.pop() ;
        if ( cst != dis [ nod ] )   continue ;
        for ( it = v [ nod ].begin() ; it != v [ nod ].end() ; ++ it )  {
            if ( cap [ nod ][ *it ] )   {
                new_d = dis [ nod ] + dist [ nod ] + cost [ nod ][ *it ] - dist [ *it ] ;
                if ( new_d < dis [ *it ] )  {
                    dis [ *it ] = new_d ;
                    real_d [ *it ] = real_d [ nod ] + cost [ nod ][ *it ] ;
                    t [ *it ] = nod ;
                    qu.push( { *it , dis [ *it ] } ) ;
                }
            }
        }
    }
    if ( dis [ d ] == oo )  return 0 ;
    flow = oo ;
    for ( i = d ; i != s ; i = t [ i ] )
        flow = min ( flow , cap [ t [ i ] ][ i ] ) ;
    for ( i = d ; i != s ; i = t [ i ] )    {
        cap [ t [ i ] ][ i ] -= flow ;
        cap [ i ][ t [ i ] ] += flow ;
    }
    ans += flow * real_d [ d ] ;
    return 1 ;
}
void bellman () {
    int i , nod ;
    for ( i = 1 ; i <= n ; ++ i ) dist [ i ] = oo ;
    queue < int > q ;
    dist [ s ] = 0 ;
    q.push( s ) ;
    while ( !q.empty() )    {
        nod = q.front() ;
        q.pop() ;
        inq [ nod ] = 0 ;
        for ( it = v [ nod ].begin() ; it != v [ nod ].end() ; ++ it )
            if ( cap [ nod ][ *it ] )
            if ( dist [ nod ] + cost [ nod ][ *it ] < dist [ *it ] )   {
                dist [ *it ] = dist [ nod ] + cost [ nod ] [ *it ] ;
                if ( !inq [ *it ] ) {
                    q.push( *it ) ;
                    inq [ *it ] = 1 ;
                }
            }
    }
}
int main () {
    in >> n >> m >> s >> d ;
    while ( m -- )  {
        in >> x >> y >> c >> z ;
        v [ x ].pb ( y ) ;
        v [ y ].pb ( x ) ;
        cap [ x ][ y ] = c ;
        cost [ x ][ y ] = z ;
        cost [ y ][ x ] = -z ;
    }
    bellman() ;
    while ( dijkstra() ) ;
    out << ans ;
}