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

#include <bits/stdc++.h>
#ifdef __LOCAL
#define DBG(X) cout << #X << " = " << (X) << endl;
#define SAY(X) cout << (X) << endl;
#include <filesystem>
namespace fs = std::filesystem;
#else
#define DBG(X)
#define SAY(X)
#endif

using namespace std;

using ll = long long int;
using ull = unsigned long long int;
using ld = long double;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
using ppll = pair<ll, pll>;

int dx[] = {1, 0, -1, 0, 1, -1, 1, -1};
int dy[] = {0, 1, 0, -1, 1, 1, -1, -1};
const int INT_INF = (int)(2e9);
const ll LL_INF = (ll)(2e18);
static mt19937 _g(time(nullptr));

inline ll randint(ll a, ll b) {
  ll w = (_g() << 31LL) ^ _g();
  return a + w % (b - a + 1);
}
inline void fast_io() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  cout.tie(nullptr);
};
template <typename T, typename S>
inline ostream &operator<<(ostream &os, const pair<T, S> p) {
  cout << "[" << p.first << ";" << p.second << "]";
  return os;
}
template <typename T, typename S>
inline ostream &operator<<(ostream &os, const map<T, S> p) {
  for (auto el : p)
    cout << "[" << el.first << ";" << el.second << "]";
  return os;
}
template <typename T>
inline ostream &operator<<(ostream &os, const vector<T> &v) {
  for (auto el : v)
    cout << el << " ";
  return os;
}
template <typename T> inline vector<T> fetch_vec(int sz) {
  vector<T> ret(sz);
  for (auto &elem : ret)
    cin >> elem;
  return ret;
}

ll N, M, S;

struct edge {
  ll to, cost, time;
  edge(ll to, ll c, ll t) : to(to), cost(c), time(t) {}
};

vector<vector<edge>> G;
ll A = 0;
void input() {
  fast_io();
#ifdef __LOCAL
  fs::path __p = __FILE__;
  fs::path __input, __output;
  __input = __output = __p.parent_path();
  __input += string("/input/") + string(__p.stem()) + string(".txt");
  __output += string("/output/") + string(__p.stem()) + string(".txt");
  freopen(__input.c_str(), "r", stdin);
  freopen(__output.c_str(), "w", stdout);
#endif
  cin >> N >> M >> S;
  G.resize(N);

  for (int i = 0; i < M; i++) {
    ll u, v;
    ll a, b;
    cin >> u >> v >> a >> b;
    u--, v--;
    G.at(u).emplace_back(v, a, b);
    G.at(v).emplace_back(u, a, b);
    A = max(A, a);
  }
  for (int i = 0; i < N; i++) {
    ll c, d;
    cin >> c >> d;
    G.at(i).emplace_back(i, -c, d);
  }
}

vector<ll> dijkstra() {
  priority_queue<ppll, vector<ppll>, greater<ppll>> pq;
  vector<vector<ll>> dist(N, vector<ll>(50 * N + 1, LL_INF));
  // vector<ll> dist(50*N*N+N+1, INT_INF);

  S = min(S, 50 * N);
  for (int i = 0; i <= S; i++)
    dist.at(0).at(i) = 0LL;
  // for (int i = 0; i <= S; i++) dist.at(0+N*i) = 0;

  pq.emplace(0, make_pair(0, S));
  while (!pq.empty()) {
    ll c_time;
    pll cur;
    tie(c_time, cur) = pq.top();
    ll idx = cur.first;
    ll coin = cur.second;
    pq.pop();

    if (dist.at(idx).at(coin) < c_time)
      continue;
    // if(dist.at(idx+N*coin) < c_time) continue;
    for (auto next : G.at(idx)) {
      if (next.cost > coin)
        continue;
      ll ntime, nidx, ncoin;
      ntime = c_time + next.time;
      nidx = next.to;
      ncoin = coin - next.cost;
      ncoin = min(ncoin, 50 * N);
      if (dist.at(nidx).at(ncoin) <= ntime)
        continue;
      // if(dist.at(nidx+N*ncoin) <= ntime) continue;
      dist.at(nidx).at(ncoin) = ntime;
      // dist.at(nidx+N*ncoin) = ntime;
      pq.emplace(ntime, make_pair(nidx, ncoin));
    }
  }
  vector<ll> ret(N, LL_INF);
  for (int i = 0; i < N; i++)
    ret.at(i) = *min_element(dist.at(i).begin(), dist.at(i).end());
  // for (int i = 0; i < N; i++) {
  //     for (int j = 0; j <= 50*N; j++)
  //     {
  //         ret.at(i) = min(ret.at(i), dist.at(i+N*j));
  //     }

  // }
  // DBG(dist)
  return ret;
}

int solve() {
  auto ans = dijkstra();
  for (int i = 1; i < N; i++)
    cout << ans.at(i) << "\\n";

  return 0;
}

int main() {
  input();
  solve();
  return 0;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#ifdef __LOCAL
#define DBG(X) cout << #X << " = " << (X) << endl;
#define SAY(X) cout << (X) << endl;
#include <filesystem>
namespace fs = std::filesystem;
#else
#define DBG(X)
#define SAY(X)
#endif

using namespace std;

using ll = long long int;
using ull = unsigned long long int;
using ld = long double;
using pii = pair<int, int>;
using pll = pair<ll, ll>;

int dx[] = {1, 0, -1, 0, 1, -1, 1, -1};
int dy[] = {0, 1, 0, -1, 1, 1, -1, -1};
const int INT_INF = (int)(2e9);
const ll LL_INF = (ll)(2e18);
static mt19937 _g(time(nullptr));

inline ll randint(ll a, ll b) {
  ll w = (_g() << 31LL) ^ _g();
  return a + w % (b - a + 1);
}
inline void fast_io() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  cout.tie(nullptr);
};
template <typename T, typename S>
inline ostream &operator<<(ostream &os, const pair<T, S> p) {
  cout << "[" << p.first << ";" << p.second << "]";
  return os;
}
template <typename T, typename S>
inline ostream &operator<<(ostream &os, const map<T, S> p) {
  for (auto el : p)
    cout << "[" << el.first << ";" << el.second << "]";
  return os;
}
template <typename T>
inline ostream &operator<<(ostream &os, const vector<T> &v) {
  for (auto el : v)
    cout << el << " ";
  return os;
}
template <typename T> inline vector<T> fetch_vec(int sz) {
  vector<T> ret(sz);
  for (auto &elem : ret)
    cin >> elem;
  return ret;
}

int N, M;
ll S;

struct edge {
  ll to, cost, time;
  edge(ll to, ll c, ll t) : to(to), cost(c), time(t) {}
};

vector<vector<edge>> G;
vector<pll> City;
vector<vector<ll>> costs;
vector<vector<ll>> times;
void input() {
  fast_io();
#ifdef __LOCAL
  fs::path __p = __FILE__;
  fs::path __input, __output;
  __input = __output = __p.parent_path();
  __input += string("/input/") + string(__p.stem()) + string(".txt");
  __output += string("/output/") + string(__p.stem()) + string(".txt");
  freopen(__input.c_str(), "r", stdin);
  freopen(__output.c_str(), "w", stdout);
#endif
  cin >> N >> M >> S;
  G.resize(N);
  costs.assign(N, vector<ll>(N, INT_INF));
  times.assign(N, vector<ll>(N, INT_INF));

  for (int i = 0; i < M; i++) {
    int u, v;
    ll a, b;
    cin >> u >> v >> a >> b;
    u--, v--;
    costs[u][v] = costs[v][u] = a;
    times[u][v] = times[v][u] = b;
    G[u].emplace_back(v, a, b);
    G[v].emplace_back(u, a, b);
  }
  for (int i = 0; i < N; i++) {
    ll c, d;
    cin >> c >> d;
    City.emplace_back(c, d);
    G[i].emplace_back(i, -c, d);
  }
}

void chmin(ll &a, ll b) {
  if (a < b)
    a = b;
}

int wrong_solve() {
  vector<map<ll, ll>> dp(N);
  for (int i = 0; i < N; i++) {
    for (int j = 0; j <= 5000; j++) {
      dp[i][j] = INT_INF;
    }
  }
  for (int j = 0; j <= S; j++)
    dp[0][j] = 0;

  int l = 0;
  while ((S + l * City[0].first) <= 5000) {
    dp[0][S + l * City[0].first] = l * City[0].second;
    l++;
  }
  // DBG(dp[0])
  queue<int> q;
  vector<bool> visited(N, false);
  q.push(0);
  int cnt = 0;
  while (!q.empty()) {
    int cur;
    // ll money;
    // tie(money,cur) = q.front();
    cur = q.front();
    if (visited[cur])
      cnt++;
    if (cnt >= 3 * N)
      break;
    visited[cur] = true;
    q.pop();
    for (auto next : G[cur]) {
      // if(dp[next.to][money-next.cost] < dp[cur][money]+next.time) continue;
      for (int j = 0; j < 5000; j++) {
        if (dp[next.to][j] > dp[cur][j + next.cost] + next.time)
          dp[next.to][j] = dp[cur][j + next.cost] + next.time;
        if (dp[next.to][j + City[next.to].first] >
            (dp[next.to][j] + City[next.to].second))
          dp[next.to][j + City[next.to].first] =
              (dp[next.to][j] + City[next.to].second);
        // chmin(dp[next.to][j+City[next.to].first],
        // (dp[next.to][j]+City[next.to].second));
      }
      // ll nem = money-next.cost;
      // chmin(dp[next.to][nem],dp[cur][money]+next.time);
      // chmin(dp[next.to][nem+City[next.to].first],dp[next.to][nem]+City[next.to].second);

      q.push(next.to);
      // q.emplace(nem, next.to);
    }
  }
  // DBG(dp)
  // auto cmp = [](const auto& l, const auto& r) { return l.second > r.second;
  // };
  for (int i = 1; i < N; i++) {
    // SAY("a")
    // DBG(dp[i])
    ll ans = INT_INF;
    for (int j = 0; j < 100; j++) {
      ans = min(ans, dp[i][j]);
    }

    // auto itr = *min_element(dp[i].begin(),dp[i].end(),cmp);
    cout << ans << endl;
  }

  return 0;
}

struct point {
  ll t, c, idx;
  point(ll t, ll c, ll i) : t(t), c(c), idx(i) {}
};

bool operator<(const point &p1, const point &p2) { return p1.t > p2.t; }

vector<ll> memo;
ll dijkstra() {
  // if(memo[t]) return memo[t];
  priority_queue<point> pq;
  vector<bool> visited(N, false);
  int cnt = 0;
  pq.emplace(0, S, 0);
  while (!pq.empty()) {
    point cur = pq.top();
    pq.pop();
    // if(cur.idx==t) return memo[cur.idx] = cur.t;
    if (!visited[cur.idx]) {
      cnt++;
      memo[cur.idx] = cur.t;
    }
    if (cnt == N)
      break;
    visited[cur.idx] = true;
    // point stay = cur;
    // stay.c += City[cur.idx].first;
    // stay.t += City[cur.idx].second;
    // pq.push(stay);
    for (auto u : G[cur.idx]) {
      if (u.cost <= cur.c) {
        point next = cur;
        next.t += u.time;
        next.idx = u.to;
        next.c -= u.cost;
        if (next.c >= 5000 && u.cost < 0)
          continue;
        pq.push(next);
      }
    }
  }
  return -1;
}

int solve() {
  // ワーシャルフロイド
  // ダメ。最小コスト経路と最短時間経路が異なる場合がある。
  // 最小コスト経路で銀貨がSを超えなくても最短経路ではそうでない可能性がある。
  // for (int k = 0; k < N; k++)
  //     for (int i = 0; i < N; i++)
  //         for (int j = 0; j < N; j++)
  //         {
  //             chmin(costs[i][j],costs[i][k]+costs[k][j]);
  //             chmin(times[i][j],times[i][k]+times[k][j]);
  //         }

  // vector<ll> ans;
  memo.assign(N, 0);
  dijkstra();
  for (int i = 1; i < N; i++)
    cout << memo[i] << "\\n";

  // for (int i = 1; i < N; i++) ans.push_back(dijkstra(i));
  // for(auto a:ans) cout << a << endl;
  return 0;
}

int main() {
  input();
  solve();
  return 0;
}