Problem p02703 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <bits/stdc++.h>
using namespace std;

#define ll long long
#define rep(i, x, y) for (int i = x; i < y; i++)
#define rel(i, x, y) for (int i = x - 1; i >= y; i--)
#define all(x) x.begin(), x.end()
ll inf = 1e18 + 7;
int main() {
  cin.tie(nullptr);
  ios::sync_with_stdio(false);
  cout << fixed << setprecision(15);
  int n, m, s;
  cin >> n >> m >> s;
  vector<vector<tuple<ll, ll, ll>>> graph(n); // time_cost,money,next
  vector<ll> c(n);                            // get_money
  vector<ll> d(n);                            // time_cost
  rep(i, 0, m) {
    int a, b, q, w;
    cin >> a >> b >> q >> w;
    a--;
    b--;
    graph[a].push_back(make_tuple(w, q, b));
    graph[b].push_back(make_tuple(w, q, a));
  }
  rep(i, 0, n) cin >> c[i] >> d[i];
  priority_queue<tuple<ll, ll, ll>, vector<tuple<ll, ll, ll>>,
                 greater<tuple<ll, ll, ll>> // time,money,locate
                 >
      que;
  int money = (s < 2500 ? s : 2500);
  que.push(make_tuple(0, money, 0));
  ll dist[51][2510]; // 答えのメモ
  rep(i, 0, 51) rep(j, 0, 2510) dist[i][j] = inf;
  dist[0][money] = 0; // startは0

  // dijkstra
  while (!que.empty()) {
    auto [time, money, locate] = que.top();
    que.pop();
    if (dist[locate][money] < time)
      continue;
    if (money < 2500) { // お金を増やす側の移動を行うフェイズ
      ll add_money = c[locate] + money;
      if (add_money > 2500)
        add_money = 2500;
      ll add_time = time + d[locate];
      if (dist[locate][add_money] > add_time) {
        dist[locate][add_money] = add_time;
        que.push(make_tuple(add_time, add_money, locate)); // 時間とお金のみ増
      }
    }
    // 駅を移動するフェイズ
    rep(i, 0, graph[locate].size()) {
      tuple<ll, ll, ll> next = graph[locate][i]; // time,money,locate
      int next_locate = get<2>(next);
      ll next_money = money - get<1>(next);
      ll next_time = time + get<0>(next);
      if (next_money < 0)
        continue;
      // dist更新
      if (dist[next_locate][next_money] > next_time) {
        dist[next_locate][next_money] = next_time;
        que.push(make_tuple(next_time, next_money, next_locate));
      }
    }
  }
  rep(i, 1, n) {
    ll ans = inf;
    rep(j, 0, 2500) { ans = min(ans, dist[i][j]); }
    cout << ans << endl;
  }
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;

#define ll long long
#define rep(i, x, y) for (int i = x; i < y; i++)
#define rel(i, x, y) for (int i = x - 1; i >= y; i--)
#define all(x) x.begin(), x.end()
ll inf = 1e18 + 7;
int main() {
  cin.tie(nullptr);
  ios::sync_with_stdio(false);
  cout << fixed << setprecision(15);
  int n, m, s;
  cin >> n >> m >> s;
  vector<vector<tuple<ll, ll, ll>>> graph(n); // time_cost,locate,add_money
  vector<ll> c(n);                            // get_money
  vector<ll> d(n);                            // time_cost
  rep(i, 0, m) {
    int a, b, q, w;
    cin >> a >> b >> q >> w;
    a--;
    b--;
    graph[a].push_back(make_tuple(w, b, q));
    graph[b].push_back(make_tuple(w, a, q));
  }
  rep(i, 0, n) cin >> c[i] >> d[i];
  priority_queue<tuple<ll, ll, ll>, vector<tuple<ll, ll, ll>>,
                 greater<tuple<ll, ll, ll>> // time,current,money
                 >
      que;
  int money = (s < 2510 ? s : 2510);
  que.push(make_tuple(0, 0, money));
  ll dist[51][2510]; // 答えのメモ
  rep(i, 0, 51) rep(j, 0, 2510) dist[i][j] = inf;
  dist[0][money] = 0; // startは0

  // dijkstra
  while (!que.empty()) {
    auto [time, locate, money] = que.top();
    que.pop();
    if (dist[locate][money] < time)
      continue;
    dist[locate][money] = time;
    if (money < 2510) { // お金を増やす側の移動を行うフェイズ
      ll add_money = c[locate] + money;
      if (add_money > 2510)
        add_money = 2510;
      ll add_time = time + d[locate];
      if (dist[locate][add_money] > add_time) {
        que.push(make_tuple(add_time, locate, add_money)); // 時間とお金のみ増
      }
    }
    // 駅を移動するフェイズ
    rep(i, 0, graph[locate].size()) {
      tuple<ll, ll, ll> next = graph[locate][i]; // time,money,locate
      int next_locate = get<1>(next);
      ll next_money = money - get<2>(next);
      ll next_time = time + get<0>(next);
      if (next_money < 0)
        continue;
      // dist更新
      if (dist[next_locate][next_money] > next_time) {
        que.push(make_tuple(next_time, next_locate, next_money));
      }
    }
  }
  rep(i, 1, n) {
    ll ans = inf;
    rep(j, 0, 2510) { ans = min(ans, dist[i][j]); }
    cout << ans << endl;
  }
}