Cod sursa(job #305770)

Utilizator DastasIonescu Vlad Dastas Data 18 aprilie 2009 15:53:36
Problema Flux maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.21 kb
#include <cstdio>
#include <iostream>
#include <vector>
#include <bitset>

using namespace std;

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

FILE *in = fopen("fmcm.in","r"), *out = fopen("fmcm.out","w");

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

vector <short> g[maxn];

int ok;

void read()
{
    fscanf(in, "%hd %hd %hd %hd", &n, &m, &s, &d);

    short x, y, fluxcap, cost;
    for ( int i = 1; i <= m; ++i )
    {
        fscanf(in, "%hd %hd %hd %hd", &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(short &x, short &y)
{
    return x < y ? x : y;
}

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

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

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

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

        for ( 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 ( i = d; i != s; i = tata[i] )
        fmin = min(fmin, cap[ tata[i] ][i] - flux[ tata[i] ][i]);

    for ( 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();

    fprintf(out, "%d\n", go());

    return 0;
}