Cod sursa(job #2669991)

Utilizator retrogradLucian Bicsi retrograd Data 8 noiembrie 2020 17:11:15
Problema Flux maxim de cost minim Scor 10
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.84 kb
#include <bits/stdc++.h>

using namespace std;
const int kInf = 1e9;

struct CCFlow {
  struct Edge {
    int to, f, c, k;
    int res() { return c - f; }
  };

  int n;
  vector<Edge> es;
  vector<vector<int>> graph;
  vector<int> in;
  vector<long long> dist;
  long long cost = 0;

  CCFlow(int n) : n(n), graph(n), in(n), dist(n) {}

  int AddEdge(int a, int b, int c, int k) {
    auto go = [&](int a, int b, int c, int k) {
      graph[a].push_back(es.size());
      es.push_back(Edge{ b, 0, c, k });
    };
    go(a, b, c, k);
    go(b, a, 0, -k);
    return es.size() - 2;
  }

  pair<int, int> dfs(int node, int f) {
    if (in[node])
      return { node, f };

    in[node] = true;
    for (auto ei : graph[node]) {
      auto& e = es[ei];
      if (dist[e.to] <= dist[node] + e.k || e.res() == 0)
        continue;
      dist[e.to] = dist[node] + e.k;

      int until, aug;
      tie(until, aug) = dfs(e.to, min(f, e.res()));

      if (until != -1) {
        es[ei].f += aug;
        es[ei ^ 1].f -= aug;
        cost += 1LL * aug * es[ei].k;
        if (until == node) until = -1;
      }

      if (aug) return { until, aug };
    }
    in[node] = false;
    return { -1, 0 };
  }

  int iterate() {
    fill(in.begin(), in.end(), 0);
    fill(dist.begin(), dist.end(), 0);
    for (int i = 0; i < n; ++i) {
      int flow = dfs(i, kInf).second;
      if (flow > 0) return flow;
    }
    return 0;
  }

  long long Solve() {
    while (iterate());
    return cost;
  }
};

int main() {
  ifstream cin("fmcm.in");
  ofstream cout("fmcm.out");

  int n, m, s, t; cin >> n >> m >> s >> t; --s; --t;
  CCFlow mf(n);
  for (int i = 0; i < m; ++i) {
    int a, b, c, k; cin >> a >> b >> c >> k;
    mf.AddEdge(a - 1, b - 1, c, k);
  }
  mf.AddEdge(t, s, kInf, -kInf);
  long long cost = mf.Solve();
  while (cost < -kInf) cost += kInf;
  cout << cost << endl;

  return 0;
}