Cod sursa(job #2499210)

Utilizator FunnyStockyMihnea Andreescu FunnyStocky Data 25 noiembrie 2019 17:47:05
Problema Flux maxim de cost minim Scor 20
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.08 kb
#include <cstdio>
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>

using namespace std;

const int Y = 350 + 7;
const int I = (int) 1e9;
int y;
int m;
int s;
int d;
int o[Y][Y];
int w[Y][Y];
vector<int> g[Y];
int worst[Y];
int par[Y];

struct State
{
    int a;
    int d;
};

bool operator < (State a, State b)
{
    return a.d > b.d;
}

int main()
{
    freopen ("fmcm.in", "r", stdin);
    freopen ("fmcm.out", "w", stdout);

    cin >> y >> m >> s >> d;
    for (int i = 1; i <= m; i++)
    {
        int a, b;
        cin >> a >> b;
        cin >> o[a][b] >> w[a][b];
        g[a].push_back(b);
        g[b].push_back(a);
        w[b][a] = -w[a][b];
    }
    int v = 0;
    while (1)
    {
        for (int i = 1; i <= y; i++)
        {
            worst[i] = I;
        }
        worst[s] = 0;
        priority_queue<State> p;
        p.push({s, 0});
        while (!p.empty())
        {
            auto it = p.top();
            p.pop();
            if (worst[it.a] != it.d)
            {
                break;
            }
            int a = it.a;
            for (auto &b : g[a])
            {
                if (o[a][b] && worst[a] + w[a][b] < worst[b])
                {
                    worst[b] = worst[a] + w[a][b];
                    par[b] = a;
                    p.push({b, worst[b]});
                }
            }
        }
        vector<int> nodes;
        int t = d;
        while (t)
        {
            nodes.push_back(t);
            t = par[t];
        }
        reverse(nodes.begin(), nodes.end());
        int l = I;
        for (int i = 0; i + 1 < (int) nodes.size(); i++)
        {
            l = min(l, o[nodes[i]][nodes[i + 1]]);
        }
        for (int i = 0; i + 1 < (int) nodes.size(); i++)
        {
            int a = nodes[i];
            int b = nodes[i + 1];
            o[a][b] -= l;
            o[b][a] += l;
            v += w[a][b] * l;
        }
        if (l == 0)
        {
            break;
        }
    }
    cout << v << "\n";
}