Problem p02377 (C++) — buggy submission, verdict: Runtime Error

#include <algorithm>
#include <bitset>
#include <cassert>
#include <complex>
#include <cstdio>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

using namespace std;
#define DBG(...) ;

using LL = long long;
constexpr LL LINF = 334ll << 53;
constexpr int INF = 15 << 26;
constexpr LL MOD = 1E9 + 7;

class MinimumCostFlow {
  struct Edge {
    int to;
    long long cost, capacity;
    int rev_id;
    Edge(int to, long long cost, long long cap, int id)
        : to(to), cost(cost), capacity(cap), rev_id(id){};
    Edge() { Edge(0, 0, 0, 0); }
  };
  struct Prev {
    LL cost;
    int from, id;
  };
  using Graph = vector<vector<Edge>>;
  using Flow = vector<vector<long long>>;
  int n;
  Graph graph;
  Flow flow;
  vector<Prev> prev;
  vector<long long> potential;

public:
  MinimumCostFlow(int n)
      : n(n), graph(n), flow(n, vector<long long>(n)), prev(n, {LINF, -1, -1}),
        potential(n) {}
  void addEdge(int a, int b, long long cap, long long cost) {
    graph[a].emplace_back(b, cost, cap, (int)graph[b].size());
    graph[b].emplace_back(a, -cost, 0, (int)graph[a].size() - 1);
  }
  long long minimumCostFlow(int s, int t, LL f) {
    LL ret = 0;
    // int size = graph.size();
    // vector<LL> h(size);
    // vector<Prev> prev(size, {LINF, -1, -1});  //mincost, from,id
    for (bellman_ford(s); f > 0; dijkstra(s)) {
      if (prev[t].cost == LINF)
        return -1;
      for (int i = 0; i < n; ++i)
        potential[i] = min(potential[i] + prev[i].cost, LINF);
      LL d = f;
      for (int v = t; v != s; v = prev[v].from) {
        // DBG(v)
        // DBG(prev[v].from)
        d = min(d, graph[prev[v].from][prev[v].id].capacity -
                       flow[prev[v].from][v]);
        // DBG(d)
      }
      f -= d;
      ret += d * potential[t];
      // DBG(ret)
      for (int v = t; v != s; v = prev[v].from) {
        flow[prev[v].from][v] += d;
        flow[v][prev[v].from] -= d;
      }
    }
    return ret;
  }

private:
  bool dijkstra(const int start) {
    int visited = 0, N = graph.size();
    fill(prev.begin(), prev.end(), (Prev){LINF, -1, -1});
    typedef tuple<LL, int, int, int> TP;
    priority_queue<TP, vector<TP>, greater<TP>> pque;
    pque.emplace(0, start, 0, -1);
    LL cost;
    int place, from, id;
    while (!pque.empty()) {
      tie(cost, place, from, id) = pque.top();
      pque.pop();
      if (prev[place].from != -1)
        continue;
      prev[place] = {cost, from, id};
      visited++;
      if (visited == N)
        return true;
      for (int i = 0; i < (int)graph[place].size(); ++i) {
        auto e = &graph[place][i];
        if (e->capacity > flow[place][e->to] && prev[e->to].from == -1) {
          pque.emplace(e->cost + cost - potential[e->to] + potential[place],
                       e->to, place, i);
        }
      }
    }
    return false;
  }
  bool bellman_ford(const int start) {
    int s = graph.size();
    bool update = false;
    prev[start] = (Prev){0ll, start, -1};
    for (int i = 0; i < s; ++i, update = false) {
      for (int j = 0; j < s; ++j) {
        int k = 0;
        for (auto &e : graph[j]) {
          if (e.capacity == 0)
            continue;
          if (prev[j].cost != LINF && prev[e.to].cost > prev[j].cost + e.cost) {
            prev[e.to].cost = prev[j].cost + e.cost;
            prev[e.to].from = j;
            prev[e.to].id = k;
            update = true;
            if (i == s - 1)
              return false;
          }
          ++k;
        }
      }
      if (!update)
        break;
    }
    return true;
  }
};

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  int n, m;
  LL flow;
  cin >> n >> m >> flow;
  MinimumCostFlow mcf(n);
  for (int i = 0; i < m; i++) {
    int a, b;
    LL cost, cap;
    cin >> a >> b >> cap >> cost;
    mcf.addEdge(a, b, cap, cost);
  }
  cout << mcf.minimumCostFlow(0, n - 1, flow) << endl;
  return 0;
}


Error: -11

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cassert>
#include <complex>
#include <cstdio>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

using namespace std;
#define DBG(...) ;

using LL = long long;
constexpr LL LINF = 334ll << 53;
constexpr int INF = 15 << 26;
constexpr LL MOD = 1E9 + 7;

struct Edge {
  int from, to;
  LL cost, capacity;
  int rev_id;
};
typedef vector<vector<Edge>> Graph;
typedef vector<vector<LL>> Flow;
struct Prev {
  LL cost;
  int from, id;
};
class MinimumCostFlow {
  struct Edge {
    int to;
    long long cost, capacity;
    int rev_id;
    Edge(int to, long long cost, long long cap, int id)
        : to(to), cost(cost), capacity(cap), rev_id(id){};
    Edge() { Edge(0, 0, 0, 0); }
  };
  struct Prev {
    LL cost;
    int from, id;
  };
  using Graph = vector<vector<Edge>>;
  using Flow = vector<vector<long long>>;
  int n;
  Graph graph;
  Flow flow;
  vector<Prev> prev;
  vector<long long> potential;

public:
  MinimumCostFlow(int n)
      : n(n), graph(n), prev(n, {LINF, -1, -1}), potential(n) {}
  void addEdge(int a, int b, long long cap, long long cost) {
    graph[a].emplace_back(b, cost, cap, (int)graph[b].size());
    graph[b].emplace_back(a, -cost, 0, (int)graph[a].size() - 1);
  }
  long long minimumCostFlow(int s, int t, LL f) {
    LL ret = 0;
    // int size = graph.size();
    // vector<LL> h(size);
    // vector<Prev> prev(size, {LINF, -1, -1});  //mincost, from,id
    for (bellman_ford(s); f > 0; dijkstra(s)) {
      if (prev[t].cost == LINF)
        return -1;
      for (int i = 0; i < n; ++i)
        potential[i] = min(potential[i] + prev[i].cost, LINF);
      LL d = f;
      for (int v = t; v != s; v = prev[v].from) {
        // DBG(v)
        // DBG(prev[v].from)
        d = min(d, graph[prev[v].from][prev[v].id].capacity -
                       flow[prev[v].from][v]);
        // DBG(d)
      }
      f -= d;
      ret += d * potential[t];
      // DBG(ret)
      for (int v = t; v != s; v = prev[v].from) {
        flow[prev[v].from][v] += d;
        flow[v][prev[v].from] -= d;
      }
    }
    return ret;
  }

private:
  bool dijkstra(const int start) {
    int visited = 0, N = graph.size();
    fill(prev.begin(), prev.end(), (Prev){LINF, -1, -1});
    typedef tuple<LL, int, int, int> TP;
    priority_queue<TP, vector<TP>, greater<TP>> pque;
    pque.emplace(0, start, 0, -1);
    LL cost;
    int place, from, id;
    while (!pque.empty()) {
      tie(cost, place, from, id) = pque.top();
      pque.pop();
      if (prev[place].from != -1)
        continue;
      prev[place] = {cost, from, id};
      visited++;
      if (visited == N)
        return true;
      for (int i = 0; i < (int)graph[place].size(); ++i) {
        auto e = &graph[place][i];
        if (e->capacity > flow[place][e->to] && prev[e->to].from == -1) {
          pque.emplace(e->cost + cost - potential[e->to] + potential[place],
                       e->to, place, i);
        }
      }
    }
    return false;
  }
  bool bellman_ford(const int start) {
    int s = graph.size();
    bool update = false;
    prev[start] = (Prev){0ll, start, -1};
    for (int i = 0; i < s; ++i, update = false) {
      for (int j = 0; j < s; ++j) {
        for (auto &e : graph[j]) {
          if (e.capacity == 0)
            continue;
          if (prev[j].cost != LINF && prev[e.to].cost > prev[j].cost + e.cost) {
            prev[e.to].cost = prev[j].cost + e.cost;
            prev[e.to].from = j;
            prev[e.to].id = e.rev_id;
            update = true;
            if (i == s - 1)
              return false;
          }
        }
      }
      if (!update)
        break;
    }
    return true;
  }
};
int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  int n, m;
  LL flow;
  cin >> n >> m >> flow;
  MinimumCostFlow mcf(n);
  for (int i = 0; i < m; i++) {
    int a, b;
    LL cost, cap;
    cin >> a >> b >> cap >> cost;
    mcf.addEdge(a, b, cap, cost);
  }
  cout << mcf.minimumCostFlow(0, n - 1, flow) << endl;
  return 0;
}