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

#include <bits/stdc++.h>

using namespace std;

using ll = long long;
using ld = long double;

using vi = vector<int>;
using vvi = vector<vi>;
using vll = vector<ll>;
using vvll = vector<vll>;
using vb = vector<bool>;
using vs = vector<string>;

typedef pair<ll, ll> P;

#define bit(n) (1LL << (n))

// #define int long long

#define all(v) v.begin(), v.end()

#define rep(i, n) for (ll i = 0; i < n; i++)
#define REP(i, n) for (ll i = 1; i < n; i++)

#define FOR(i, a, b) for (ll i = (a); i < (b); i++)
#define FORm(i, m) for (auto i = m.begin(); i != m.end(); i++)

template <class T> inline void chmax(T &a, T b) { a = std::max(a, b); }
template <class T> inline void chmin(T &a, T b) { a = std::min(a, b); }

#define mod (ll)(1e9 + 7)
const long long INF = 1LL << 60;

vll c, d;

// Dijkstra
// O(Elog(V))
struct Dijkstra {
  struct Edge {
    int to;
    ll cost;
    long long time;
  };

  vector<vector<Edge>> G;
  int num_v;
  vector<priority_queue<P, vector<P>, greater<P>>> vinfo;

public:
  Dijkstra(int max_v) : G(max_v), num_v(max_v), vinfo(max_v) {}

  void add_edge(int from, int to, long long cost, long long time) {
    G[from].push_back((Edge){to, cost, time});
  }

  void solve(int s, ll initial_silver) {
    // P.first : time
    // P.second: index
    // P.third: money
    using T = tuple<ll, ll, ll>;
    priority_queue<T, vector<T>, greater<T>> que;

#define MAX_SILVER ((ll)2500)

    chmin(initial_silver, MAX_SILVER);

    // memo[v][num_silver]: vにいて銀貨をnum_silver枚持っている状態の最小時間
    vvll memo(num_v + 1, vll(MAX_SILVER + 1, INF));

    que.emplace(0, s, initial_silver);

    while (!que.empty()) {
      T p = que.top();
      que.pop();

      ll t = get<0>(p);
      int v = get<1>(p);
      ll sil = get<2>(p);
      chmin(sil, (ll)MAX_SILVER);

      // より少ないコストでの経路が見つかっている場合
      if (memo[v][sil] <= t) {
        continue;
      }
      rep(i, sil + 1) { chmin(memo[v][i], t); }

      // vの各辺に対しよりコストの低い経路があるかを確認
      for (auto &e : G[v]) {
        ll silver = sil - e.cost;
        if (silver >= 0) {
          if (memo[e.to][silver] > t) {
            que.emplace(t + e.time, e.to, silver);
          }
        }
      }

      // 換金
      ll new_c = min(sil + c[v], MAX_SILVER);
      if (memo[v][new_c] > t) {
        que.emplace(t + d[v], v, new_c);
      }
    }

    FOR(i, 2, num_v) { cout << *min_element(all(memo[i])) << endl; }
  }

  vector<int> get_path(const vector<int> &prev, int t) {
    vector<int> path;

    for (int v = t; v != -1; v = prev[v]) {
      path.push_back(v);
    }

    reverse(path.begin(), path.end());
    return path;
  }
};

signed main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  cout << fixed << setprecision(20);

  ll n, m, s;
  cin >> n >> m >> s;

  Dijkstra graph(n + 1);

  rep(i, m) {
    int u, v;
    ll a, b;
    cin >> u >> v >> a >> b;
    graph.add_edge(u, v, a, b);
    graph.add_edge(v, u, a, b);
  }

  c = vll(n + 1);
  d = vll(n + 1);

  REP(i, n + 1) { cin >> c[i] >> d[i]; }

  graph.solve(1, s);

  return 0;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>

using namespace std;

using ll = long long;
using ld = long double;

using vi = vector<int>;
using vvi = vector<vi>;
using vll = vector<ll>;
using vvll = vector<vll>;
using vb = vector<bool>;
using vs = vector<string>;

typedef pair<ll, ll> P;

#define bit(n) (1LL << (n))

// #define int long long

#define all(v) v.begin(), v.end()

#define rep(i, n) for (ll i = 0; i < n; i++)
#define REP(i, n) for (ll i = 1; i < n; i++)

#define FOR(i, a, b) for (ll i = (a); i < (b); i++)
#define FORm(i, m) for (auto i = m.begin(); i != m.end(); i++)

template <class T> inline void chmax(T &a, T b) { a = std::max(a, b); }
template <class T> inline void chmin(T &a, T b) { a = std::min(a, b); }

#define mod (ll)(1e9 + 7)
const long long INF = 1LL << 60;

vll c, d;

// Dijkstra
// O(Elog(V))
struct Dijkstra {
  struct Edge {
    int to;
    ll cost;
    long long time;
  };

  vector<vector<Edge>> G;
  int num_v;
  vector<priority_queue<P, vector<P>, greater<P>>> vinfo;

public:
  Dijkstra(int max_v) : G(max_v), num_v(max_v), vinfo(max_v) {}

  void add_edge(int from, int to, long long cost, long long time) {
    G[from].push_back((Edge){to, cost, time});
  }

  void solve(int s, ll initial_silver) {
    // P.first : time
    // P.second: index
    // P.third: money
    using T = tuple<ll, ll, ll>;
    priority_queue<T, vector<T>, greater<T>> que;

#define MAX_SILVER 2500

    chmin(initial_silver, (ll)MAX_SILVER);

    // memo[v][num_silver]: vにいて銀貨をnum_silver枚持っている状態の最小時間
    vvll memo(num_v + 1, vll(MAX_SILVER + 1, INF));

    rep(i, initial_silver + 1) { memo[s][i] = 0; }

    que.emplace(0, s, initial_silver);

    while (!que.empty()) {
      T p = que.top();
      que.pop();

      ll t = get<0>(p);
      int v = get<1>(p);
      ll sil = get<2>(p);
      chmin(sil, (ll)MAX_SILVER);

      // より少ないコストでの経路が見つかっている場合
      if (memo[v][sil] < t) {
        continue;
      }
      rep(i, sil + 1) { chmin(memo[v][i], t); }

      // vの各辺に対しよりコストの低い経路があるかを確認
      for (auto &e : G[v]) {
        ll silver = sil - e.cost;
        if (silver >= 0) {
          if (memo[e.to][silver] > t) {
            que.emplace(t + e.time, e.to, silver);
          }
        }
      }

      // 換金
      ll new_c = min(sil + c[v], (ll)MAX_SILVER);
      if (memo[v][new_c] > t) {
        que.emplace(t + d[v], v, new_c);
      }
    }

    FOR(i, 2, num_v) { cout << *min_element(all(memo[i])) << endl; }
  }

  vector<int> get_path(const vector<int> &prev, int t) {
    vector<int> path;

    for (int v = t; v != -1; v = prev[v]) {
      path.push_back(v);
    }

    reverse(path.begin(), path.end());
    return path;
  }
};

signed main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  cout << fixed << setprecision(20);

  ll n, m, s;
  cin >> n >> m >> s;

  Dijkstra graph(n + 1);

  rep(i, m) {
    int u, v;
    ll a, b;
    cin >> u >> v >> a >> b;
    graph.add_edge(u, v, a, b);
    graph.add_edge(v, u, a, b);
  }

  c = vll(n + 1);
  d = vll(n + 1);

  REP(i, n + 1) { cin >> c[i] >> d[i]; }

  graph.solve(1, s);

  return 0;
}