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

#include <algorithm>
#include <cmath>
#include <ctime>
#include <iostream>
#include <queue>
#include <vector>

using namespace std;
using ll = long long;
using vi = vector<int>;
using vvi = vector<vector<int>>;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
using ppi = pair<pii, int>;

#define INF (ll)1e18

struct edge {
  ll to, a, b;
};

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  int ti = clock();
  // start-----------------------------------------------
  ll n, m, s;
  cin >> n >> m >> s;
  vector<vector<edge>> edges(n);
  vector<ll> c(n), d(n);
  ll max_a = 0;
  for (int i = 0; i < m; i++) {
    ll u, v, a, b;
    cin >> u >> v >> a >> b;
    u--, v--;
    edges[u].push_back({v, a, b});
    edges[v].push_back({u, a, b});
    max_a = max(max_a, (ll)a);
  }
  for (int i = 0; i < n; i++) {
    cin >> c[i] >> d[i];
  }

  priority_queue<pair<pll, pll>, vector<pair<pll, pll>>,
                 greater<pair<pll, pll>>>
      q;

  q.push({{0, 0}, {0, min((ll)max_a * (n - 1), s)}});
  ll t, cost, point, silver;
  bool f;
  vector<ll> ans(n, INF);
  vector<vector<ll>> used(n, vector<ll>(max_a * (n - 1) + 1, INF));
  while (!q.empty()) {
    // auto now = q.top(); q.pop();
    // t = now.first.first;
    // cost = now.first.second;
    // point = now.second.first;
    // silver = now.second.second;
    tie(t, cost) = q.top().first;
    tie(point, silver) = q.top().second;
    q.pop();
    if (used[point][silver] <= t)
      continue;
    used[point][silver] = t;
    ans[point] = min(ans[point], t);
    // cout << t << ' ' << point << ' ' << silver << ' ' << q.size() << endl;
    if (used[point][min(max_a * (n - 1), silver + c[point])] > t + d[point])
      q.push({{t + d[point], cost},
              {point, min(max_a * (n - 1), silver + c[point])}});
    for (auto e : edges[point]) {
      if (silver >= e.a && used[e.to][silver - e.a] > t + e.b)
        q.push({{t + e.b, cost + e.a},
                {e.to, min(max_a * (n - 1), silver - e.a)}});
    }
  }

  for (int i = 1; i < n; i++) {
    cout << ans[i] << endl;
  }

  // end-----------------------------------------------
  // cerr << 1.0 * (clock() - ti) / CLOCKS_PER_SEC << endl;
}


Error: TLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <ctime>
#include <iostream>
#include <queue>
#include <vector>

using namespace std;
using ll = long long;
using vi = vector<int>;
using vvi = vector<vector<int>>;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
using ppi = pair<pii, int>;

int f_dir[2][4] = {{-1, 0, 1, 0}, {0, 1, 0, -1}}; // ↑→↓←
int e_dir[2][8] = {{-1, -1, -1, 0, 0, 1, 1, 1}, {-1, 0, 1, -1, 1, -1, 0, 1}};
bool is_in_field(int y, int x, int h, int w) {
  return (y >= 0 && y < h && x >= 0 && x < w);
}

#define INF (ll)1e18

struct edge {
  ll a, b;
};

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  int ti = clock();
  // start-----------------------------------------------
  ll n, m, s;
  cin >> n >> m >> s;
  vector<vector<edge>> edges(n, vector<edge>(n, {INF, INF}));
  vector<ll> c(n), d(n);
  ll max_a = 0;
  for (int i = 0; i < m; i++) {
    int u, v, a, b;
    cin >> u >> v >> a >> b;
    u--, v--;
    edges[u][v] = {a, b};
    edges[v][u] = {a, b};
    max_a = max(max_a, (ll)a);
  }
  for (int i = 0; i < n; i++) {
    cin >> c[i] >> d[i];
  }

  priority_queue<pair<pll, pll>, vector<pair<pll, pll>>,
                 greater<pair<pll, pll>>>
      q;

  q.push({{0, 0}, {0, min((ll)max_a * (n - 1), s)}});
  auto now = q.top();
  ll t, cost, point, silver, coin;
  bool f;
  vector<ll> ans(n, INF);
  vector<vector<ll>> used(n, vector<ll>(max_a * (n - 1) + 1, INF));
  while (!q.empty()) {
    now = q.top();
    q.pop();
    t = now.first.first;
    cost = now.first.second;
    point = now.second.first;
    silver = now.second.second;
    if (used[point][silver] <= t)
      continue;
    used[point][silver] = t;
    ans[point] = min(ans[point], t);
    f = false;
    for (int i = 0; i < n; i++) {
      if (ans[i] == INF)
        f = true;
      if (i == point || edges[point][i].b == INF)
        continue;
      coin = 0;
      while (silver + coin * c[point] - edges[point][i].a <=
             max_a * (n - 1) - cost) {
        if (silver + coin * c[point] >= edges[point][i].a &&
            used[i][silver + coin * c[point] - edges[point][i].a] >
                t + coin * d[point] + edges[point][i].b)
          q.push({{t + coin * d[point] + edges[point][i].b,
                   cost + edges[point][i].a},
                  {(ll)i, min((ll)max_a * (n - 1),
                              silver + coin * c[point] - edges[point][i].a)}});
        coin++;
      }
    }
    if (!f)
      break;
  }

  for (int i = 1; i < n; i++) {
    cout << ans[i] << endl;
  }

  // end-----------------------------------------------
  // cerr << 1.0 * (clock() - ti) / CLOCKS_PER_SEC << endl;
}