Problem p02703 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>

const int INF = 1e9;
const int MOD = 1e9 + 7;

using namespace std;

typedef long long ll;

#define REP(i, n) for (int i = 0; i < int(n); i++)
#define REPD(i, n) for (int i = n - 1; i >= 0; i--)
#define FOR(i, a, b) for (int i = a; i < int(b); i++)
#define FORD(i, a, b) for (int i = b - 1; i >= int(a); i--)
#define WRAP(y, x, h, w) (0 <= y && y < h && 0 <= x && x < w)

#define ALL(x) (x).begin(), (x).end()

int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};

struct str {
  ll time;
  int city;
  ll money;
  bool operator<(const str &right) const {
    return time != right.time   ? time < right.time
           : city != right.city ? city < right.city
                                : money < right.money;
  }
};

int main() {
  int n, m;
  ll money;
  cin >> n >> m >> money;
  vector<vector<pair<ll, ll>>> edge(n, vector<pair<ll, ll>>(n, {-1, -1}));
  REP(i, m) {
    int u, v;
    ll a, b;
    cin >> u >> v >> a >> b;
    u--;
    v--;
    edge[u][v] = {a, b};
    edge[v][u] = {a, b};
  }
  vector<pair<ll, ll>> change(n);
  REP(i, n) {
    ll c, d;
    cin >> c >> d;
    change[i] = {c, d};
  }
  vector<vector<ll>> time(n, vector<ll>(2501, 1e18)); // city money
  set<str> sstr;
  sstr.insert({0, 0, money});
  time[0][money] = 0;
  set<int> visited;
  visited.insert(0);
  while (1) {
    auto it = sstr.begin();
    str now = *it;
    sstr.erase(it);
    visited.insert(now.city);
    if (visited.size() == n) {
      break;
    }
    ll a = now.money;
    ll b = 0;
    while (1) {
      if (time[now.city][a] > now.time + b) {
        time[now.city][a] = now.time + b;
        sstr.insert({now.time + b, now.city, a});
      }
      if (a == 2500)
        break;
      a += change[now.city].first;
      if (a > 2500)
        a = 2500;
      b += change[now.city].second;
    }
    REP(i, n) {
      if (edge[now.city][i].first != -1) {
        if (now.money >= edge[now.city][i].first) {
          if (time[i][now.money - edge[now.city][i].first] >
              now.time + edge[now.city][i].second) {
            time[i][now.money - edge[now.city][i].first] =
                now.time + edge[now.city][i].second;
            sstr.insert({now.time + edge[now.city][i].second, i,
                         now.money - edge[now.city][i].first});
          }
        }
      }
    }
  }
  FOR(i, 1, n) {
    ll ans = 1e18;
    REP(j, 2501) { ans = min(ans, time[i][j]); }
    cout << ans << endl;
  }
}

Fixed submission:
#include <bits/stdc++.h>

const int INF = 1e9;
const int MOD = 1e9 + 7;

using namespace std;

typedef long long ll;

#define REP(i, n) for (int i = 0; i < int(n); i++)
#define REPD(i, n) for (int i = n - 1; i >= 0; i--)
#define FOR(i, a, b) for (int i = a; i < int(b); i++)
#define FORD(i, a, b) for (int i = b - 1; i >= int(a); i--)
#define WRAP(y, x, h, w) (0 <= y && y < h && 0 <= x && x < w)

#define ALL(x) (x).begin(), (x).end()

int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};

struct str {
  ll time;
  int city;
  ll money;
  bool operator<(const str &right) const {
    return time != right.time   ? time < right.time
           : city != right.city ? city < right.city
                                : money < right.money;
  }
};

int main() {
  int n, m;
  ll money;
  cin >> n >> m >> money;
  money = min(money, 2500LL);
  vector<vector<pair<ll, ll>>> edge(n, vector<pair<ll, ll>>(n, {-1, -1}));
  REP(i, m) {
    int u, v;
    ll a, b;
    cin >> u >> v >> a >> b;
    u--;
    v--;
    edge[u][v] = {a, b};
    edge[v][u] = {a, b};
  }
  vector<pair<ll, ll>> change(n);
  REP(i, n) {
    ll c, d;
    cin >> c >> d;
    change[i] = {c, d};
  }
  vector<vector<ll>> time(n, vector<ll>(2501, 1e18)); // city money
  set<str> sstr;
  sstr.insert({0, 0, money});
  time[0][money] = 0;
  set<int> visited;
  visited.insert(0);
  while (1) {
    auto it = sstr.begin();
    str now = *it;
    sstr.erase(it);
    visited.insert(now.city);
    if (visited.size() == n) {
      break;
    }
    ll a = now.money;
    ll b = 0;
    while (1) {
      if (time[now.city][a] > now.time + b) {
        time[now.city][a] = now.time + b;
        sstr.insert({now.time + b, now.city, a});
      }
      if (a == 2500)
        break;
      a += change[now.city].first;
      if (a > 2500)
        a = 2500;
      b += change[now.city].second;
    }
    REP(i, n) {
      if (edge[now.city][i].first != -1) {
        if (now.money >= edge[now.city][i].first) {
          if (time[i][now.money - edge[now.city][i].first] >
              now.time + edge[now.city][i].second) {
            time[i][now.money - edge[now.city][i].first] =
                now.time + edge[now.city][i].second;
            sstr.insert({now.time + edge[now.city][i].second, i,
                         now.money - edge[now.city][i].first});
          }
        }
      }
    }
  }
  FOR(i, 1, n) {
    ll ans = 1e18;
    REP(j, 2501) { ans = min(ans, time[i][j]); }
    cout << ans << endl;
  }
}