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

#include <cassert>
#include <cstdio>
#include <limits>
#include <queue>
#include <tuple>
#include <utility>
#include <vector>
using namespace std;

struct MinCostFlowGraph {
private:
  using ll = long long;
  struct edge {
    int to;
    ll cap, cost;
    int r_idx;
    edge(int t, ll cap, ll cost, int r)
        : to(t), cap(cap), cost(cost), r_idx(r) {}
  };
  vector<vector<edge>> G;
  int sz;
  vector<ll> calc_potential(int from) {
    queue<int> Q;
    Q.emplace(from);
    vector<ll> ret(sz, numeric_limits<int>::max() / 2);
    ret[from] = 0;
    vector<int> d_in(sz, 0);
    for (int i = 0; i < sz; ++i) {
      for (auto e : G[i]) {
        if (e.cap <= 0)
          continue;
        ++d_in[e.to];
      }
    }
    while (Q.size()) {
      auto v = Q.front();
      Q.pop();
      for (auto e : G[v]) {
        if (e.cap <= 0)
          continue;
        int v_ = e.to;
        ret[v_] = min(ret[v_], ret[v] + e.cost);
        --d_in[v_];
        if (!d_in[v_])
          Q.emplace(v_);
      }
    }
    return ret;
  }

public:
  MinCostFlowGraph(int n) : G(n), sz(n) {}

  void add_edge(int from, int to, ll cap, ll cost) {
    int i = G[to].size(), i_ = G[from].size();
    G[from].emplace_back(to, cap, cost, i);
    G[to].emplace_back(from, 0, -cost, i_);
  }

  ll min_cost_flow(int from, int to, ll f) {
    ll ans = 0;
    const ll INF = numeric_limits<int>::max() / 2;
    vector<ll> potential = calc_potential(from);
    while (f > 0) {
      vector<ll> dist(sz, INF);
      dist[from] = 0;
      vector<int> prev_v(sz, -1);
      vector<int> prev_e(sz, -1);
      priority_queue<pair<ll, int>, vector<pair<ll, int>>, greater<>> pq;
      pq.emplace(0, from);
      while (pq.size()) {
        auto [d, v] = pq.top();
        // d *= -1;
        pq.pop();
        if (dist[v] < d)
          continue;
        for (size_t i = 0; i < G[v].size(); ++i) {
          const auto &e = G[v][i];
          if (e.cap == 0)
            continue;
          int v_ = e.to;
          ll d_ = d + e.cost + potential[v] - potential[v_];
          if (dist[v_] <= d_)
            continue;
          dist[v_] = d_;
          prev_v[v_] = v;
          prev_e[v_] = i;
          // pq.emplace(-d_,e.to);
          pq.emplace(d_, e.to);
        }
      }
      // if(dist[to] >= INF) return -1;
      for (int i = 0; i < sz; ++i)
        potential[i] += dist[i];
      int v = to;
      ll flow = f;
      while (v != from) {
        int v_ = prev_v[v];
        flow = min(flow, G[v_][prev_e[v]].cap);
        v = v_;
      }
      v = to;
      while (v != from) {
        int v_ = prev_v[v];
        auto &e = G[v_][prev_e[v]];
        e.cap -= flow;
        ans += flow * e.cost;
        G[v][e.r_idx].cap += flow;
        v = v_;
      }
      f -= flow;
    }
    return ans;
  }
};

#include <iostream>
#include <vector>
using namespace std;

int main() {
  int N, M;
  cin >> N >> M;
  vector<string> S(N);
  for (int i = 0; i < N; ++i) {
    cin >> S[i];
  }
  MinCostFlowGraph G(N * M + 2);
  int source = N * M, sink = source + 1;
  int c = 0, INF = 1e9;
  for (int i = 0; i < N; ++i) {
    for (int j = 0; j < M; ++j) {
      if (S[i][j] == '#')
        continue;
      int v = i * M + j;
      if (S[i][j] == 'o') {
        ++c;
        G.add_edge(source, v, 1, 0);
      }
      if (i + 1 < N)
        G.add_edge(v, v + M, INF, -1);
      if (j + 1 < M)
        G.add_edge(v, v + 1, INF, -1);
      G.add_edge(v, sink, 1, 0);
    }
  }
  cout << -G.min_cost_flow(source, sink, c) << '\\n';
}


Error: 0

Fixed submission:

#include <cassert>
#include <cstdio>
#include <limits>
#include <queue>
#include <tuple>
#include <utility>
#include <vector>
using namespace std;

struct MinCostFlowGraph {
private:
  using ll = long long;
  struct edge {
    int to;
    ll cap, cost;
    int r_idx;
    edge(int t, ll cap, ll cost, int r)
        : to(t), cap(cap), cost(cost), r_idx(r) {}
  };
  vector<vector<edge>> G;
  int sz;
  vector<ll> calc_potential(int from) {
    queue<int> Q;
    Q.emplace(from);
    vector<ll> ret(sz, numeric_limits<int>::max() / 2);
    ret[from] = 0;
    vector<int> d_in(sz, 0);
    for (int i = 0; i < sz; ++i) {
      for (auto e : G[i]) {
        if (e.cap <= 0)
          continue;
        ++d_in[e.to];
      }
    }
    while (Q.size()) {
      auto v = Q.front();
      Q.pop();
      for (auto e : G[v]) {
        if (e.cap <= 0)
          continue;
        int v_ = e.to;
        ret[v_] = min(ret[v_], ret[v] + e.cost);
        --d_in[v_];
        if (!d_in[v_])
          Q.emplace(v_);
      }
    }
    return ret;
  }

public:
  MinCostFlowGraph(int n) : G(n), sz(n) {}

  void add_edge(int from, int to, ll cap, ll cost) {
    int i = G[to].size(), i_ = G[from].size();
    G[from].emplace_back(to, cap, cost, i);
    G[to].emplace_back(from, 0, -cost, i_);
  }

  ll min_cost_flow(int from, int to, ll f) {
    ll ans = 0;
    const ll INF = numeric_limits<int>::max() / 2;
    vector<ll> potential = calc_potential(from);
    while (f > 0) {
      vector<ll> dist(sz, INF);
      dist[from] = 0;
      vector<int> prev_v(sz, -1);
      vector<int> prev_e(sz, -1);
      priority_queue<pair<ll, int>, vector<pair<ll, int>>, greater<>> pq;
      pq.emplace(0, from);
      while (pq.size()) {
        auto [d, v] = pq.top();
        // d *= -1;
        pq.pop();
        if (dist[v] < d)
          continue;
        for (size_t i = 0; i < G[v].size(); ++i) {
          const auto &e = G[v][i];
          if (e.cap == 0)
            continue;
          int v_ = e.to;
          ll d_ = d + e.cost + potential[v] - potential[v_];
          if (dist[v_] <= d_)
            continue;
          dist[v_] = d_;
          prev_v[v_] = v;
          prev_e[v_] = i;
          // pq.emplace(-d_,e.to);
          pq.emplace(d_, e.to);
        }
      }
      if (dist[to] >= INF)
        return -1;
      for (int i = 0; i < sz; ++i)
        potential[i] += dist[i];
      int v = to;
      ll flow = f;
      while (v != from) {
        int v_ = prev_v[v];
        flow = min(flow, G[v_][prev_e[v]].cap);
        v = v_;
      }
      v = to;
      while (v != from) {
        int v_ = prev_v[v];
        auto &e = G[v_][prev_e[v]];
        e.cap -= flow;
        ans += flow * e.cost;
        G[v][e.r_idx].cap += flow;
        v = v_;
      }
      f -= flow;
    }
    return ans;
  }
};

#include <iostream>
#include <vector>
using namespace std;

int main() {
  int N, M;
  cin >> N >> M;
  vector<string> S(N);
  for (int i = 0; i < N; ++i) {
    cin >> S[i];
  }
  MinCostFlowGraph G(N * M + 2);
  int source = N * M, sink = source + 1;
  int c = 0, INF = 1e9;
  for (int i = 0; i < N; ++i) {
    for (int j = 0; j < N; ++j) {
      if (S[i][j] == '#')
        continue;
      int v = i * M + j;
      if (S[i][j] == 'o') {
        ++c;
        G.add_edge(source, v, 1, 0);
      }
      if (i + 1 < N)
        G.add_edge(v, v + M, INF, -1);
      if (j + 1 < M)
        G.add_edge(v, v + 1, INF, -1);
      G.add_edge(v, sink, 1, 0);
    }
  }
  cout << -G.min_cost_flow(source, sink, c) << '\\n';
}