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

#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); i++)
using namespace std;
using ll = long long;

const ll VMAX = 50;
const ll SMAX = VMAX * 50;
const ll INF = 1LL << 60;

struct Edge {
  ll to, a, b;
  Edge(ll to, ll a, ll b) : to(to), a(a), b(b) {}
};

struct Node {
  ll v;    // ノード
  ll t, s; // 時間 , 所持金
  Node(ll v, ll t, ll s) : v(v), t(t), s(s) {}

  bool operator<(const Node &x) const { return (t > x.t); }
};

vector<Edge> V[VMAX];
vector<pair<ll, ll>> C;
ll dp[VMAX][SMAX]; // dp[i][j] : 頂点iで所持金jのときの最短時間

int main() {
  ll n, m, s;
  cin >> n >> m >> s;
  s = min(s, SMAX - 1);

  rep(i, m) {
    ll u, v, a, b;
    cin >> u >> v >> a >> b;
    u--;
    v--;
    V[u].push_back(Edge(v, a, b));
    V[v].push_back(Edge(u, a, b));
  }
  C.resize(n);
  rep(i, n) {
    ll c, d;
    cin >> c >> d;
    C[i] = make_pair(c, d);
  }

  priority_queue<Node> Q;
  auto push = [&](ll v, ll t, ll s) {
    if (s < 0)
      return; // お金が足りないとreturn
    if (dp[v][s] <= t)
      return; // 既に他の最適経路があればreturn
    dp[v][s] = t;
    Q.emplace(v, t, s);
  };

  rep(i, VMAX) rep(j, SMAX) dp[i][j] = INF;
  push(0, 0, s);
  while (!Q.empty()) {
    auto node = Q.top();
    Q.pop();
    ll v = node.v;
    ll t = node.t;
    ll s = node.s;
    if (dp[v][s] != t)
      continue;

    // 換金するパターン
    ll c = C[v].first;
    ll d = C[v].second;
    push(v, t + d, min(s + c, SMAX - 1));

    // 別のノードにいくパターン
    for (Edge x : V[v]) {
      ll a = x.a;
      ll b = x.b;
      ll to = x.to;
      push(to, t + b, s - a);
    }
  }

  for (int i = 1; i < n; i++) {
    ll ans = INF;
    rep(j, SMAX) { ans = min(ans, dp[i][j]); }
    cout << ans << endl;
  }

  return 0;
}

Error: 0

Fixed submission:

#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); i++)
using namespace std;
using ll = long long;

const ll VMAX = 50;
const ll SMAX = VMAX * 50;
const ll INF = 1LL << 60;

struct Edge {
  ll to, a, b;
  Edge(ll to, ll a, ll b) : to(to), a(a), b(b) {}
};

struct Node {
  ll v;    // ノード
  ll t, s; // 時間 , 所持金
  Node(ll v, ll t, ll s) : v(v), t(t), s(s) {}

  bool operator<(const Node &x) const { return (t > x.t); }
};

vector<Edge> V[VMAX];
vector<pair<ll, ll>> C;
ll dp[VMAX][SMAX]; // dp[i][j] : 頂点iで所持金jのときの最短時間

int main() {
  ll n, m, s;
  cin >> n >> m >> s;
  s = min(s, SMAX - 1);

  rep(i, m) {
    ll u, v, a, b;
    cin >> u >> v >> a >> b;
    u--;
    v--;
    V[u].push_back(Edge(v, a, b));
    V[v].push_back(Edge(u, a, b));
  }
  C.resize(n);
  rep(i, n) {
    ll c, d;
    cin >> c >> d;
    C[i] = make_pair(c, d);
  }

  priority_queue<Node> Q;
  auto push = [&](ll v, ll t, ll s) {
    if (s < 0)
      return; // お金が足りないとreturn
    if (dp[v][s] <= t)
      return; // 既に他の最適経路があればreturn
    dp[v][s] = t;
    Q.emplace(v, t, s);
  };

  rep(i, VMAX) rep(j, SMAX) dp[i][j] = INF;
  push(0, 0, s);
  while (!Q.empty()) {
    auto node = Q.top();
    Q.pop();
    ll v = node.v;
    ll t = node.t;
    ll s = node.s;
    if (dp[v][s] != t)
      continue;

    // 換金するパターン
    ll c = C[v].first;
    ll d = C[v].second;
    push(v, t + d, min(s + c, SMAX));

    // 別のノードにいくパターン
    for (Edge x : V[v]) {
      ll a = x.a;
      ll b = x.b;
      ll to = x.to;
      push(to, t + b, s - a);
    }
  }

  for (int i = 1; i < n; i++) {
    ll ans = INF;
    rep(j, SMAX) { ans = min(ans, dp[i][j]); }
    cout << ans << endl;
  }

  return 0;
}