Cod sursa(job #305764)

Utilizator DastasIonescu Vlad Dastas Data 18 aprilie 2009 15:39:08
Problema Flux maxim de cost minim Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 2.12 kb
#include <fstream>
#include <iostream>
#include <vector>

using namespace std;

const int maxn = 351;
const int inf = 1 << 30;

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

int n, m, s, d;
int cap[maxn][maxn]; // capacitatile
int flux[maxn][maxn];
int cst[maxn][maxn];
int dist[maxn];
int coada[maxn];
int viz[maxn];
int tata[maxn];

vector <int> g[maxn];

int ok;

void read()
{
    in >> n >> m >> s >> d;

    int x, y, fluxcap, cost;
    for ( int i = 1; i <= m; ++i )
    {
        in >> x >> y >> fluxcap >> cost;

        g[x].push_back(y);
        g[y].push_back(x);

        cap[x][y] = fluxcap;

        cst[x][y] = cost;
        cst[y][x] = -cost;
    }
}

inline int min(int x, int y)
{
    return x < y ? x : y;
}

int BellmanFord()
{
    for ( int i = 1; i <= n; ++i )
        dist[i] = inf, viz[i] = 0;

    int p = 0, u = 0;
    coada[p] = s;
    dist[s] = 0;
    viz[s] = 1;

    while ( p <= u )
    {
        int x = coada[p++];
        viz[x] = 0;

//        if ( viz[ tata[x] ] )
//            continue;

        for ( unsigned int i = 0; i < g[x].size(); ++i )
            if ( cap[x][ g[x][i] ] - flux[x][ g[x][i] ] > 0 && dist[x] + cst[x][ g[x][i] ] < dist[ g[x][i] ] )
            {
                dist[ g[x][i] ] = dist[x] + cst[x][ g[x][i] ];
                tata[ g[x][i] ] = x;

                if ( !viz[ g[x][i] ] )
                {
                    coada[++u] = g[x][i];
                    viz[ g[x][i] ] = 1;
                }
            }
    }

    if ( dist[d] == inf )
        return 0;

    ok = 1;

    int fmin = inf;

    for ( int i = d; i != s; i = tata[i] )
        fmin = min(fmin, cap[ tata[i] ][i] - flux[ tata[i] ][i]);

    for ( int i = d; i != s; i = tata[i] )
    {
        flux[ tata[i] ][i] += fmin;
        flux[i][ tata[i] ] -= fmin;
    }

    return fmin * dist[d];
}

int go()
{
    ok = 1;
    int rez = 0;

    while ( ok )
    {
        ok = 0;
        rez += BellmanFord();
    }

    return rez;
}

int main()
{
    read();

    out << go() << endl;

    return 0;
}