Cod sursa(job #379515)

Utilizator DastasIonescu Vlad Dastas Data 2 ianuarie 2010 01:02:14
Problema Flux maxim de cost minim Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.48 kb
#include <fstream>
#include <vector>
#include <queue>
#include <utility>

using namespace std;

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

typedef pair<int, int> PER;

int s, d;

void citire(vector<int> G[], int &N, int &M, int C[maxn][maxn], int CS[maxn][maxn])
{
    ifstream in("fmcm.in");
    in >> N >> M >> s >> d;

    for ( int i = 1; i <= N; ++i )
        for ( int j = 1; j <= N; ++j )
            CS[i][j] = 0;

    int x, y, cap, cst;
    for ( int i = 1; i <= M; ++i )
    {
        in >> x >> y >> cap >> cst;
        G[x].push_back(y);
        G[y].push_back(x);

        C[x][y] = cap;

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

    in.close();
}

int dijkstra(vector<int> G[], int N, int C[maxn][maxn], int F[maxn][maxn], int CS[maxn][maxn], int P[], int D[])
{
    for ( int i = 1; i <= N; ++i )
        D[i] = inf;
    D[s] = 0;

    priority_queue<PER, vector<PER>, greater<PER> > Q;

    Q.push( make_pair(D[s], s) );
    while ( !Q.empty() )
    {
        PER tmp = Q.top();
        Q.pop();

        int min = tmp.second;
        if ( tmp.first != D[min] )
            continue;

        vector<int>::iterator i;
        for ( i = G[min].begin(); i != G[min].end(); ++i )
            if ( D[min] + CS[min][*i] < D[*i] && C[min][*i] - F[min][*i] > 0 )
            {
                D[*i] = D[min] + CS[min][*i];
                P[*i] = min;

                Q.push( make_pair(D[*i], *i) );
            }
    }

    return D[d];
}

int Flux(vector<int> G[],
               int N,
               int C[maxn][maxn],
               int CS[maxn][maxn])
{
    int F[maxn][maxn], P[maxn], D[maxn];
    for ( int i = 1; i <= N; ++i )
        for ( int j = 1; j <= N; ++j )
            F[i][j] = 0;
    P[s] = 0;

    int cst_min = 0, tmp_cst;
    while ( (tmp_cst = dijkstra(G, N, C, F, CS, P, D)) != inf )
    {
        int min = inf;

        for ( int x = d; x != s; x = P[x] )
            if ( C[ P[x] ][x] - F[ P[x] ][x] < min )
                min = C[ P[x] ][x] - F[ P[x] ][x];

        for ( int x = d; x != s; x = P[x] )
        {
            F[ P[x] ][x] += min;
            F[x][ P[x] ] -= min;
        }

        cst_min += tmp_cst * min;
    }

    return cst_min;
}

int main()
{
    int N, M, C[maxn][maxn], CS[maxn][maxn];
    vector<int> G[maxn];

    citire(G, N, M, C, CS);

    ofstream out("fmcm.out");
    out << Flux(G, N, C, CS);
    out.close();

    return 0;
}