Cod sursa(job #3220370)

Utilizator tibinyteCozma Tiberiu-Stefan tibinyte Data 3 aprilie 2024 13:08:26
Problema Flux maxim de cost minim Scor 50
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.35 kb
#include <bits/stdc++.h>

using namespace std;

#define cin fin
#define cout fout

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

const int inf = 1e9;

struct edge
{
    int u, v, cap, flow, cost;
};

struct Dinic
{
    vector<edge> edg;
    int n;
    int s, t;
    Dinic(int n, int s, int t) : n(n), s(s), t(t) {}
    void add_edge(int u, int v, int c, int cost)
    {
        edg.push_back({u, v, c, 0, cost});
        edg.push_back({v, u, 0, 0, -cost});
    }
    pair<int, int> bellman()
    {
        vector<int> dist(n + 1, inf);
        vector<int> par(n + 1, -1);
        dist[s] = 0;
        for (int i = 1; i < n; ++i)
        {
            for (int x = 0; x < edg.size(); ++x)
            {
                auto j = edg[x];
                if (j.cap - j.flow > 0 && dist[j.u] != inf)
                {
                    if (dist[j.u] + j.cost < dist[j.v])
                    {
                        dist[j.v] = dist[j.u] + j.cost;
                        par[j.v] = x;
                    }
                }
            }
        }
        if (dist[t] == inf)
        {
            return {0, inf};
        }
        pair<int, int> ans;
        int push = inf;
        int frog = t;
        while (frog != s)
        {
            int cap = edg[par[frog]].cap - edg[par[frog]].flow;
            push = min(push, cap);
            frog = edg[par[frog]].u;
        }
        frog = t;
        ans.first = push;
        while (frog != s)
        {
            edg[par[frog]].flow += push;
            edg[par[frog] ^ 1].flow -= push;
            ans.second += edg[par[frog]].cost * push;
            frog = edg[par[frog]].u;
        }
        return ans;
    }
    pair<int, int> flow()
    {
        pair<int, int> ans;
        while (true)
        {
            pair<int, int> add = bellman();
            if (add.first == 0)
            {
                return ans;
            }
            ans.first += add.first;
            ans.second += add.second;
        }
    }
};
int main()
{
    cin.tie(nullptr)->sync_with_stdio(false);
    int n, m, s, d;
    cin >> n >> m >> s >> d;
    Dinic G(n, s, d);
    for (int i = 1; i <= m; ++i)
    {
        int a, b, cap, cost;
        cin >> a >> b >> cap >> cost;
        G.add_edge(a, b, cap, cost);
    }
    cout << G.flow().second;
}