Cod sursa(job #1389120)

Utilizator AdrianaMAdriana Moisil AdrianaM Data 16 martie 2015 00:12:44
Problema Flux maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.53 kb
#include <fstream>
#include <vector>
#include <queue>
#define INF 0x3f3f3f3f
using namespace std;

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

using VB = vector<bool>;
using VI = vector<int>;
using VVI = vector<VI>;

int n, m, S, D;
int fmin, answ;
VB ok;
VI t, oldd, reald, d;
VVI g, cap, cost;

void Read();
void BF();
bool Dijkstra();

int main()
{
    Read();
    BF();
    t = d = reald = VI(n + 1);
    while ( Dijkstra() );
    os << answ;
    is.close();
    os.close();
    return 0;
}

bool Dijkstra()
{
    int nod, cst;
    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> q;
    d.assign(n + 1, INF);
    d[S] = reald[S] = 0;
    q.push(make_pair(0, S));
    while ( !q.empty() )
    {
        nod = q.top().second;
        cst = q.top().first;
        q.pop();
        if ( cst != d[nod] || nod == D )
            continue;
        for ( const auto &nodv : g[nod] )
            if ( cap[nod][nodv] && d[nodv] > d[nod] + cost[nod][nodv] + oldd[nod] - oldd[nodv] )
            {
                d[nodv] = d[nod] + cost[nod][nodv] + oldd[nod] - oldd[nodv];
                reald[nodv] = reald[nod] + cost[nod][nodv];
                t[nodv] = nod;
                q.push(make_pair(d[nodv], nodv));
            }
    }
    oldd = reald;
    if ( d[D] == INF )
        return false;
    fmin = INF;
    for ( int x = D; x != S; x = t[x] )
        fmin = min(fmin, cap[t[x]][x]);
    for ( int x = D; x != S; x = t[x] )
    {
        cap[t[x]][x] -= fmin;
        cap[x][t[x]] += fmin;
    }
    answ += fmin * reald[D];
    return true;
}

void BF()
{
    int nod;
    queue<int> q;
    ok = VB(n + 1);
    oldd = VI(n + 1, INF);
    q.push(S);
    oldd[S] = 0;
    while ( !q.empty() )
    {
        nod = q.front();
        q.pop();
        ok[nod] = false;
        for ( const auto &nodv : g[nod] )
            if ( cap[nod][nodv] && oldd[nodv] > oldd[nod] + cost[nod][nodv] )
            {
                oldd[nodv] = oldd[nod] + cost[nod][nodv];
                if ( !ok[nodv] )
                {
                    ok[nodv] = true;
                    q.push(nodv);
                }
            }
    }
}

void Read()
{
    is >> n >> m >> S >> D;
    g = VVI(n + 1);
    cap = cost = VVI(n + 1, VI(n + 1));
    int n1, n2;
    while ( m-- )
    {
        is >> n1 >> n2;
        g[n1].push_back(n2);
        g[n2].push_back(n1);
        is >> cap[n1][n2] >> cost[n1][n2];
        cost[n2][n1] = -cost[n1][n2];
    }
}