Cod sursa(job #1388760)

Utilizator AdrianaMAdriana Moisil AdrianaM Data 15 martie 2015 18:04:58
Problema Flux maxim de cost minim Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 2.81 kb
#include <fstream>
#include <vector>
#include <queue>
#include <set>
#include <cstring>
#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, dd;
int fmin, answ;
VB ok;
VI d, oldd, reald, t;
VVI g, cap, cost;

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

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

inline bool Dijkstra()
{
    set<pair<int, int>> q;
    q.insert(make_pair(0, s));
    d.assign(n + 1, INF);
    ok.assign(n + 1, 0);
    d[s] = reald[s] = 0;
    int nod, cst, newd;
    while ( !q.empty() )
    {
        nod = q.begin()->second;
        cst = q.begin()->first;
        q.erase(q.begin());
        if ( cst != d[nod] )
            continue;
        if ( nod == dd )
            continue;
        for ( const auto &nodv : g[nod] )
            if ( cap[nod][nodv] )
            {
                newd = d[nod] + cost[nod][nodv] + oldd[nod] - oldd[nodv];
                if ( newd < d[nodv] )
                {
                    d[nodv] = newd;
                    reald[nodv] = reald[nod] + cost[nod][nodv];
                    t[nodv] = nod;
                    if ( !ok[nodv] )
                    {
                        q.insert(make_pair(d[nodv], nodv));
                        ok[nodv] = true;;
                    }
                }
            }
    }
    oldd = reald;
    if ( d[dd] == INF )
        return false;
    fmin = INF;
    cst = 0;
    for ( int i = dd; i != s; i = t[i] )
        fmin = min(fmin, cap[t[i]][i]);
    answ += fmin * reald[dd];
    for ( int i = dd; i != s; i = t[i] )
    {
        cap[t[i]][i] -= fmin;
        cap[i][t[i]] += fmin;
    }
    return true;
}

void BF()
{
    oldd = VI(n + 1, INF);
    ok = VB(n + 1);
    oldd[s] = 0;
    int nod;
    queue<int> q;
    q.push(s);
    while ( q.size() )
    {
        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 >> dd;
    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];
    }
}