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

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

signed main() {
  // cout << fixed << setprecision(10) << flush;

  int n, m, s;
  cin >> n >> m >> s;
  vector<vector<int>> edge(n, vector<int>());
  vector<vector<int>> fare(n, vector<int>());
  vector<vector<int>> time(n, vector<int>());
  int maxa = 0;
  for (int i = 0; i < m; i++) {
    int u, v, a, b;
    cin >> u >> v >> a >> b;
    u--;
    v--;
    edge[u].push_back(v);
    edge[v].push_back(u);
    fare[u].push_back(a);
    fare[v].push_back(a);
    time[u].push_back(b);
    time[v].push_back(b);
    maxa = max(maxa, a);
  }

  vector<int> c(n), d(n);
  for (int i = 0; i < n; i++) {
    cin >> c[i] >> d[i];
  }

  // 所要時間、場所、所持銀貨
  priority_queue<tuple<int, int, int>, vector<tuple<int, int, int>>,
                 greater<tuple<int, int, int>>>
      pq;

  // dis[i][j] は 銀貨 j 枚で i にたどり着く最小時間
  vector<vector<int>> dis(n, vector<int>(maxa * n + 1, -1));
  if (s > maxa * n)
    s = maxa * n;
  pq.push(make_tuple(0, 0, s));

  auto all_visited = [&]() {
    for (int i = 0; i < n; i++) {
      bool flag = false;
      for (int j = 0; j <= maxa * n; j++) {
        if (dis[i][j] != -1) {
          flag = true;
          break;
        }
      }
      if (!flag)
        return false;
    }
    return true;
  };

  while (!all_visited()) {
    int tim = get<0>(pq.top());
    int pla = get<1>(pq.top());
    int sil = get<2>(pq.top());
    pq.pop();
    if (dis[pla][sil] == -1)
      dis[pla][sil] = tim;
    else
      continue;

    // 買わないで進むパターン
    for (int i = 0; i < edge[pla].size(); i++) {
      int next_tim = tim + time[pla][i];
      int next_pla = edge[pla][i];
      int next_sil = sil - fare[pla][i];
      if (next_sil >= 0 && dis[next_pla][next_sil] == -1) {
        pq.push(make_tuple(next_tim, next_pla, next_sil));
      }
    }

    // 一回だけ買うパターン
    if (sil + c[pla] < maxa * n) {
      if (dis[pla][sil + c[pla]] == -1) {
        pq.push(make_tuple(tim + d[pla], pla, sil + c[pla]));
      }
    } else {
      if (dis[pla][maxa * n] == -1)
        pq.push(make_tuple(tim + d[pla], pla, maxa * n));
    }
  }

  for (int i = 1; i < n; i++) {
    int min_dis = (1LL << 60);
    for (int j = 0; j <= maxa * n; j++) {
      if (dis[i][j] != -1)
        min_dis = min(min_dis, dis[i][j]);
    }
    cout << min_dis << endl;
  }

  return 0;
}

Error: TLE

Fixed submission:

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

signed main() {
  // cout << fixed << setprecision(10) << flush;

  int n, m, s;
  cin >> n >> m >> s;
  vector<vector<int>> edge(n, vector<int>());
  vector<vector<int>> fare(n, vector<int>());
  vector<vector<int>> time(n, vector<int>());
  int maxa = 0;
  for (int i = 0; i < m; i++) {
    int u, v, a, b;
    cin >> u >> v >> a >> b;
    u--;
    v--;
    edge[u].push_back(v);
    edge[v].push_back(u);
    fare[u].push_back(a);
    fare[v].push_back(a);
    time[u].push_back(b);
    time[v].push_back(b);
    maxa = max(maxa, a);
  }

  vector<int> c(n), d(n);
  for (int i = 0; i < n; i++) {
    cin >> c[i] >> d[i];
  }

  // 所要時間、場所、所持銀貨
  priority_queue<tuple<int, int, int>, vector<tuple<int, int, int>>,
                 greater<tuple<int, int, int>>>
      pq;

  // dis[i][j] は 銀貨 j 枚で i にたどり着く最小時間
  vector<vector<int>> dis(n, vector<int>(maxa * n + 1, -1));
  if (s > maxa * n)
    s = maxa * n;
  pq.push(make_tuple(0, 0, s));
  // for(int i=0; ; i++){
  //     if(s+c[0]*i < maxa*n){
  //         pq.push(make_tuple(d[0]*i, 0, s+c[0]*i));
  //     }
  //     else{
  //         pq.push(make_tuple(d[0]*i, 0, maxa*n));
  //         break;
  //     }
  // }

  auto all_visited = [&]() {
    for (int i = 0; i < n; i++) {
      bool flag = false;
      for (int j = 0; j <= maxa * n; j++) {
        if (dis[i][j] != -1) {
          flag = true;
          break;
        }
      }
      if (!flag)
        return false;
    }
    return true;
  };

  while (!all_visited()) {
    int tim = get<0>(pq.top());
    int pla = get<1>(pq.top());
    int sil = get<2>(pq.top());
    pq.pop();
    if (dis[pla][sil] == -1)
      dis[pla][sil] = tim;
    // else continue;

    // 買わないで進むパターン
    for (int i = 0; i < edge[pla].size(); i++) {
      int next_tim = tim + time[pla][i];
      int next_pla = edge[pla][i];
      int next_sil = sil - fare[pla][i];
      if (next_sil >= 0 && dis[next_pla][next_sil] == -1) {
        pq.push(make_tuple(next_tim, next_pla, next_sil));
      }
    }

    // 一回だけ買うパターン
    if (sil + c[pla] < maxa * n) {
      if (dis[pla][sil + c[pla]] == -1) {
        pq.push(make_tuple(tim + d[pla], pla, sil + c[pla]));
      }
    } else {
      if (dis[pla][maxa * n] == -1)
        pq.push(make_tuple(tim + d[pla], pla, maxa * n));
    }
  }

  for (int i = 1; i < n; i++) {
    int min_dis = (1LL << 60);
    for (int j = 0; j <= maxa * n; j++) {
      if (dis[i][j] != -1)
        min_dis = min(min_dis, dis[i][j]);
    }
    cout << min_dis << endl;
  }

  return 0;
}