Cod sursa(job #2838294)

Utilizator FunnyStockyMihnea Andreescu FunnyStocky Data 23 ianuarie 2022 12:47:43
Problema Flux maxim de cost minim Scor 50
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.39 kb
#include <iostream>
#include <vector>
#include <cstdio>
#include <queue>

using namespace std;

struct MCMF {
  const long long INFLL = (long long) 1e18;
  const int INFINT = (int) 1e9;
  int n, s, d;

  struct Edge {
    int from, to, cap, cost;
  };

  vector<Edge> edges;
  vector<int> deg;
  vector<int> verts;
  vector<int> parrent;
  vector<long long> mincost;
  vector<vector<int>> g;

  MCMF(int n, int m, int s, int d) : n(n), s(s), d(d), deg(n, 0), g(n), mincost(n), parrent(n) {
    edges.reserve(m);
  }

  void add(int a, int b, int cap, int cost) {
    edges.push_back({ a, b, cap, cost });
    edges.push_back({ b, a, 0, -cost });
    verts.push_back(a);
    verts.push_back(b);
    deg[a]++;
    deg[b]++;
  }

  pair<long long, long long> get() {
    for (int i = 0; i < n; i++) g[i].reserve(deg[i]);
    for (int i = 0; i < (int)verts.size(); i++) g[verts[i]].push_back(i);

    long long flow = 0, bestcostforflow = 0;
    while (1) {
      queue<int> q;
      for (int i = 0; i < n; i++) mincost[i] = INFLL;
      q.push(s);
      mincost[s] = 0;
      while (!q.empty()) {
        int a = q.front();
        q.pop();
        for (auto& i : g[a]) {
          if (edges[i].cap) {
            int b = edges[i].to;
            long long value_b = mincost[a] + edges[i].cost;
            if (value_b < mincost[b]) {
              mincost[b] = value_b;
              q.push(b);
              parrent[b] = i;
            }
          }
        }
      }
      if (mincost[d] == INFLL) break;
      int mn = INFINT;
      long long sumcost = 0;
      vector<int> path;
      for (int i = d; i != s; i = edges[(parrent[i] ^ 1)].to) {
        path.push_back(parrent[i]);
        mn = min(mn, edges[parrent[i]].cap);
        sumcost += edges[parrent[i]].cost;
      }
      for (auto& i : path) {
        edges[i].cap -= mn;
        edges[i ^ 1].cap += mn;
      }
      flow += mn;
      bestcostforflow += (long long) mn * sumcost;
    }
    return { flow, bestcostforflow };
  }
};

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

  int n, m, s, d;
  scanf("%d %d %d %d", &n, &m, &s, &d);
  s--;
  d--;
  MCMF flow(n, m, s, d);
  while (m--) {
    int x, y, a, b;
    scanf("%d %d %d %d", &x, &y, &a, &b);
    x--;
    y--;
    flow.add(x, y, a, b);
  }
  printf("%lld\n", flow.get().second);
}