Cod sursa(job #2081199)

Utilizator killer301Ioan Andrei Nicolae killer301 Data 4 decembrie 2017 12:57:52
Problema Flux maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.54 kb
#include <iostream>
#include <fstream>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;

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

const int MAXN = 355;
const int Inf = 0x3f3f3f3f;
struct Nod{
    int cost, nod;

    bool operator < ( const Nod& a ) const
    {
        return cost > a.cost;
    }
};
int N, M, S, D;
vector< vector<int> > G;
int F[MAXN][MAXN];
int m[MAXN][MAXN];
int c[MAXN];
int t[MAXN];
int RealCost[MAXN];
int P[MAXN];
int cmin;

void Read();
void Bellman_Ford();
bool Dijkstra();

int main()
{
    Read();
    Bellman_Ford();

    while ( Dijkstra() );

    fout << cmin << '\n';

    fin.close();
    fout.close();
    return 0;
}


void Read()
{
    fin >> N >> M >> S >> D;
    G = vector< vector<int> >(N + 1);
    int x, y, c, z;
    while ( M-- )
    {
        fin >> x >> y >> c >> z;

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

        F[x][y] = c;

        m[x][y] = z;
        m[y][x] = -z;
    }
}

void Bellman_Ford()
{
    queue<int> Q;

    P[S] = 0;
    Q.push(S);

    while ( !Q.empty() )
    {
        int node = Q.front();
        Q.pop();

        for ( const int& v : G[node] )
        {
            //cout << node << ' ' << v; cin.get();
            if ( P[v] > P[node] + 1 )
            {
                //cout << v; cin.get();
                P[v] = P[node] + 1;
                Q.push(v);
            }
        }
    }
}

bool Dijkstra()
{
    memset(c, Inf, sizeof(c));
    c[S] = RealCost[S] = 0;
    priority_queue<Nod> Q;
    Q.push({0, S});

    while ( !Q.empty() )
    {
        int node = Q.top().nod;
        int cc = Q.top().cost;
        Q.pop();

        if ( cc != c[node] ) continue;
        for ( const int& v : G[node] )
            if ( F[node][v] )
            {
                int c_nou = c[node] + P[node] - P[v] + m[node][v];

                if ( c_nou < c[v] )
                {
                    c[v] = c_nou;
                    RealCost[v] = RealCost[node] + m[node][v];
                    t[v] = node;

                    Q.push({c[v], v});
                }
            }
    }
    for ( int i = 1; i <= N; ++i )
        P[i] = RealCost[i];

    if ( c[D] >= Inf )
        return false;

    int fc{Inf};
    for ( int i = D; i != S; i = t[i] )
        fc = min( F[t[i]][i], fc );

    cmin += fc*RealCost[D];

    for ( int i = D; i != S; i = t[i] )
    {
        F[t[i]][i] -= fc;
        F[i][t[i]] += fc;
    }

    return true;
}