Cod sursa(job #3286032)

Utilizator Chris_BlackBlaga Cristian Chris_Black Data 13 martie 2025 17:51:05
Problema Flux maxim de cost minim Scor 30
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.25 kb
#include <vector>
#include <queue>
#include <fstream>
#include <algorithm>
#include <climits>
//#include <iostream>
#define vi vector<int>
#define vvi vector<vi>
#define pb push_back
#define pii pair<int, int>
#define ff first
#define ss second
#define FOR(i, a, b) for(int i = a; i <= b; ++i)
#define FORR(i, a, b) for(int i = a; i >= b; --i)

using namespace std;
const string TASK("fmcm");
ifstream fin(TASK + ".in");
ofstream fout(TASK + ".out");
#define cin fin
#define cout fout

const int N = 500 + 9, Inf = 0x3f3f3f3f;
const bool test_case = false;

int n, m, s, d;
vvi G(N);

struct edge
{
    int from, to, cap, flow, cost;
    edge(int from, int to, int cap, int flow, int cost) : from(from), to(to), cap(cap), flow(flow), cost(cost)
    {}
};
vector<edge> edges;

inline void add_edge(int x, int y, int c, int z)
{
    G[x].pb(edges.size());
    edges.pb({x, y, c, 0, z});
    G[y].pb(edges.size());
    edges.pb({y, x, 0, 0, -z});
}

int dist[N];
bool inQ[N];
inline void BellmanFord()
{
    queue<int> q;
    FOR(i, 1, n)dist[i] = Inf;
    dist[s] = 0;
    q.push(s);
    inQ[s] = true;

    while(!q.empty())
    {
        int x = q.front();
        q.pop();
        inQ[x] = false;

        for(auto i : G[x])
        {
            if(i % 2 == 0)continue;
            auto& e = edges[i];
            if(dist[e.to] > dist[e.from] + e.cost)
            {
                dist[e.to] = dist[e.from] + e.cost;
                if(!inQ[e.to])
                {
                    q.push(e.to);
                    inQ[e.to] = true;
                }
            }
        }
    }
}

int dd[N], t[N], dep[N];
inline bool Dijkstra()
{
    priority_queue<vi, vector<vi>, greater<>> q;
    FOR(i, 1, n)dd[i] = Inf;
    dd[s] = 0;
    q.push({0, 0, s});

    while(!q.empty())
    {
        auto dx = q.top()[0], dp = q.top()[1], x = q.top()[2];
        q.pop();

        if(dx > dd[x])continue;
        if(x == d)break;

        for(auto i : G[x])
        {
            auto& e = edges[i];
            if(e.flow < e.cap && dd[e.to] > dd[e.from] + dist[e.from] + e.cost - dist[e.to])
            {
                t[e.to] = i;
                dd[e.to] = dd[e.from] + dist[e.from] + e.cost - dist[e.to];
                dep[e.to] = dep[e.from] + 1;
                q.push({dd[e.to], dep[e.to], e.to});
            }
        }
    }

    return dd[d] != Inf;
}

inline int FMCM()
{
    int ret = 0;
    for(; Dijkstra();)
    {
        int flow = INT_MAX;
        for(int x = d; x != s; x = edges[t[x]].from)
            flow = min(flow, edges[t[x]].cap - edges[t[x]].flow);

        ret += flow * (dd[d] + dist[d]);

        for(int x = d; x != s; x = edges[t[x]].from)
        {
            edges[t[x]].flow += flow;
            edges[t[x] ^ 1].flow -= flow;
        }
    }
    return ret;
}

void solve()
{
    cin >> n >> m >> s >> d;

    int x, y, c, z;
    FOR(i, 1, m)
    {
        cin >> x >> y >> c >> z;
        add_edge(x, y, c, z);
    }

    BellmanFord();
    cout << FMCM() << '\n';
}

int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);
    int t = 1;
    if(test_case)cin >> t;
    while(t --)
        solve();
    return 0;
}