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

#include <bits/stdc++.h>
#define rp(i, n) for (ll i = 0; i < n; i++)
#define mp make_pair
#define mt make_tuple
using namespace std;
using ll = long long;
using P = pair<ll, ll>;
using G = vector<vector<int>>;
using PP = pair<ll, pair<ll, ll>>;
using tlll = tuple<ll, ll, ll>;
const ll INF = 1ll << 50;
ll n, m, s;
ll maxa;
ll dp[53][2510];
vector<vector<PP>> graph(53);
vector<pair<ll, ll>> changetime(53);
int main() {
  cin >> n >> m >> s;
  rp(i, m) {
    ll u, v, a, b;
    cin >> u >> v >> a >> b;
    maxa = max(maxa, a);
    graph[u].push_back(mp(v, mp(a, b)));
    graph[v].push_back(mp(u, mp(a, b)));
  }
  if (s > maxa * n)
    s = maxa * n;
  rp(i, n) {
    ll c, d;
    cin >> c >> d;
    changetime[i + 1] = mp(c, d);
  }
  rp(i, 53) {
    rp(j, 2510) { dp[i][j] = INF; }
  }
  dp[1][s] = 0;
  priority_queue<tlll, vector<tlll>, greater<tlll>> dij;
  dij.push(mt(0, 1, s));
  while (!dij.empty()) {
    tlll t = dij.top();
    dij.pop();
    int ctr = 0;
    ll time = get<0>(t);
    ll i = get<1>(t);
    ll j = get<2>(t);
    if (dp[i][j] <= time && (i != 1 || j != s))
      continue;
    dp[i][j] = time;
    for (ll c = j - 1; c >= 0; c--) {
      if (dp[i][c] > time)
        dp[i][c] = time;
      else
        break;
    }
    while (j <= maxa * n) {
      if (ctr > 0) {
        if (dp[i][j] > dp[i][j - changetime[i].first] + changetime[i].second)
          dp[i][j] = dp[i][j - changetime[i].first] + changetime[i].second;
        else
          break;
      }
      for (auto pp : graph[i]) {
        if (j >= pp.second.first)
          dij.push(
              mt(dp[i][j] + pp.second.second, pp.first, j - pp.second.first));
      }
      ctr++;
      j += changetime[i].first;
    }
  }
  for (int i = 2; i <= n; i++) {
    ll ans = 1ll << 51;
    rp(j, maxa * n) { ans = min(ans, dp[i][j]); }
    cout << ans << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#define rp(i, n) for (ll i = 0; i < n; i++)
#define mp make_pair
#define mt make_tuple
using namespace std;
using ll = long long;
using P = pair<ll, ll>;
using G = vector<vector<int>>;
using PP = pair<ll, pair<ll, ll>>;
using tlll = tuple<ll, ll, ll>;
const ll INF = 1ll << 50;
ll n, m, s;
ll maxa;
ll dp[53][2510];
vector<vector<PP>> graph(53);
vector<pair<ll, ll>> changetime(53);
int main() {
  cin >> n >> m >> s;
  rp(i, m) {
    ll u, v, a, b;
    cin >> u >> v >> a >> b;
    maxa = max(maxa, a);
    graph[u].push_back(mp(v, mp(a, b)));
    graph[v].push_back(mp(u, mp(a, b)));
  }
  if (s > maxa * n)
    s = maxa * n;
  rp(i, n) {
    ll c, d;
    cin >> c >> d;
    changetime[i + 1] = mp(c, d);
  }
  rp(i, 53) {
    rp(j, 2510) { dp[i][j] = INF; }
  }
  dp[1][s] = 0;
  priority_queue<tlll, vector<tlll>, greater<tlll>> dij;
  dij.push(mt(0, 1, s));
  while (!dij.empty()) {
    tlll t = dij.top();
    dij.pop();
    int ctr = 0;
    ll time = get<0>(t);
    ll i = get<1>(t);
    ll j = get<2>(t);
    if (dp[i][j] <= time && (i != 1 || j != s))
      continue;
    dp[i][j] = time;
    for (ll c = j - 1; c >= 0; c--) {
      if (dp[i][c] > time)
        dp[i][c] = time;
      else
        break;
    }
    while (j <= maxa * n) {
      if (ctr > 0)
        dp[i][j] = min(dp[i][j],
                       dp[i][j - changetime[i].first] + changetime[i].second);
      for (auto pp : graph[i]) {
        if (j >= pp.second.first)
          dij.push(
              mt(dp[i][j] + pp.second.second, pp.first, j - pp.second.first));
      }
      ctr++;
      j += changetime[i].first;
    }
  }
  for (int i = 2; i <= n; i++) {
    ll ans = 1ll << 51;
    rp(j, maxa * n) { ans = min(ans, dp[i][j]); }
    cout << ans << endl;
  }
  return 0;
}