Cod sursa(job #2125097)

Utilizator liviu2000Dragomirescu Liviu liviu2000 Data 7 februarie 2018 23:00:50
Problema Flux maxim de cost minim Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 3.06 kb
#include <bits/stdc++.h>
#define NMAX 351
using namespace std;

ifstream fin("fmcm.in") ;
ofstream fout("fmcm.out") ;

int cap[NMAX][NMAX] , cost[NMAX][NMAX] , flux[NMAX][NMAX] , t[NMAX] , dist[NMAX] , reald[NMAX] , newd[NMAX] ;
int s , d , n , m ;
vector<int> graf[NMAX] ;
bool viz[NMAX] ;

class compar
{
public:
    bool operator () (const int &x , const int &y)
    {
        return newd[x] < newd[y] ;
    }
};
void citire()
{
    int i , a , b , c , f ;
    fin >> n >> m >> s >> d ;
    for ( i = 1 ; i <= m ; i++ )
    {
        fin >> a >> b >> c >> f ;
        graf[a].push_back(b) ;
        graf[b].push_back(a) ;
        cap[a][b] = c ;
        cost[a][b] = f ;
        cost[b][a] = -f ;
    }
}

void BFS()
{
    int nod ;
    queue<int> Q ;
    memset(dist,0x3f3f3f3f,4*n+4);
    memset(viz,false,n+1) ;
    dist[s] = 0 ;
    viz[s] = true ;
    Q.push(s) ;
    while(!Q.empty())
    {
        nod = Q.front() ;
        Q.pop() ;
        for ( int i = 0 ; i < graf[nod].size() ; i++ )
        {
            if ( flux[nod][graf[nod][i]] < cap[nod][graf[nod][i]] && dist[graf[nod][i]] > dist[nod] + cost[nod][graf[nod][i]] )
            {
                dist[graf[nod][i]] = dist[nod] + cost[nod][graf[nod][i]] ;
                if ( viz[graf[nod][i]] == false )
                {
                    Q.push(graf[nod][i]) ;
                    viz[graf[nod][i]] = true ;
                }
            }
        }
    }
}

bool dijkstra()
{
    int nod , i ;
    priority_queue<int,vector<int>,compar> pq ;
    memset(newd,0x3f3f3f3f,4*n+4) ;
    memset(viz,false,n+1) ;
    pq.push(s) ;
    newd[s] = 0 ;
    reald[s] = 0 ;
    t[s] = s ;
    while(!pq.empty())
    {
        nod = pq.top() ;
        pq.pop() ;
        if ( viz[nod] == true )
            continue ;
        viz[nod] = true ;
        for ( i = 0 ; i < graf[nod].size() ; i++ )
        {
            if ( flux[nod][graf[nod][i]] < cap[nod][graf[nod][i]] )
            {
                if ( newd[graf[nod][i]] > newd[nod] + cost[nod][graf[nod][i]] + dist[nod] - dist[graf[nod][i]] )
                {
                    newd[graf[nod][i]] = newd[nod] + cost[nod][graf[nod][i]] + dist[nod] - dist[graf[nod][i]] ;
                    pq.push(graf[nod][i]) ;
                    reald[graf[nod][i]] = reald[nod] + cost[nod][graf[nod][i]] ;
                    t[graf[nod][i]] = nod ;
                }
            }
        }
    }
    return (newd[d]!=0x3f3f3f3f) ;
}

int main()
{
    int i , sol = 0 , fmin;
    citire() ;
    BFS() ;
    while(dijkstra())
    {
        fmin = 0x3f3f3f3f ;
        for ( i = d ; i != s ; i = t[i] )
            fmin = min(fmin,cap[t[i]][i]-flux[t[i]][i]) ;
        if ( fmin == 0 )
            continue ;
        sol = sol+reald[d]*fmin ;
        for ( i = d ; i != s ; i = t[i] )
        {
            flux[t[i]][i] = flux[t[i]][i]+fmin ;
            flux[i][t[i]] = flux[i][t[i]]-fmin ;
        }
        for ( i = 1 ; i <= n ; i++ )
            dist[i] = reald[i] ;
    }
    fout << sol ;
}