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

/*#include<iostream>
#include<bits/stdc++.h>
#include<queue>
#include<string>
#include<tuple>*/
#include <vector>
using namespace std;
using ll = long long;
struct edge {
  pair<ll, ll> to;
  ll cost, time;
};
using Graph = vector<vector<vector<edge>>>;
#define p make_pair
#define INF 100000000000000007
#define t make_tuple
#define get(a, b) get<a>(b)

void add_edge(ll from1, ll from2, ll to1, ll to2, ll cost, ll time,
              Graph &graph) {
  graph[from1][from2].push_back((edge){p(to1, to2), cost, time});
}

void dijkstra(ll s, ll S, Graph graph, vector<vector<ll>> &dis) {
  ll n = graph.size(), m = graph[0].size();
  if (S >= m) {
    dis[s][m - 1] = 0;
    S = m - 1;
  } else
    dis[s][S] = 0;
  priority_queue<tuple<ll, ll, ll>, vector<tuple<ll, ll, ll>>,
                 greater<tuple<ll, ll, ll>>>
      que;
  que.push(t(dis[s][S], s, S));
  ll v, w;
  while (!que.empty()) {
    v = get(1, que.top());
    w = get(2, que.top());
    que.pop();
    for (ll i = 0; i < graph[v][w].size(); i++) {
      edge &e = graph[v][w][i];
      if (dis[e.to.first][e.to.second] > dis[v][w] + e.time) {
        dis[e.to.first][e.to.second] = dis[v][w] + e.time;
        que.push(t(dis[e.to.first][e.to.second], e.to.first, e.to.second));
      }
    }
  }
}

int main() {
  ll N, M, S;
  cin >> N >> M >> S;
  ll u, v, a, b;
  ll maxA = 0;
  vector<vector<ll>> input(M);
  vector<vector<ll>> change(N);
  for (ll i = 0; i < M; i++) {
    cin >> u >> v >> a >> b;
    u--;
    v--;
    maxA = max(maxA, a);
    input[i].push_back(u);
    input[i].push_back(v);
    input[i].push_back(a);
    input[i].push_back(b);
  }
  Graph node(N, vector<vector<edge>>((N - 1) * maxA + 1));
  vector<vector<ll>> dis(N, vector<ll>((N - 1) * maxA + 1, INF));
  for (ll i = 0; i < N; i++) {
    cin >> a >> b;
    change[i].push_back(a);
    change[i].push_back(b);
  }

  for (ll i = 0; i < M; i++) {
    for (ll j = (N - 1) * maxA; j >= 0; j--) {
      if (j - input[i][2] >= 0) {
        add_edge(input[i][0], j, input[i][1], j - input[i][2], input[i][2],
                 input[i][3], node);
        add_edge(input[i][1], j, input[i][0], j - input[i][2], input[i][2],
                 input[i][3], node);
      } else
        break;
    }
  }

  for (ll i = 0; i < N; i++) {
    for (ll j = 0; j < maxA * (N - 1) + 1; j++) {
      if (j + change[i][0] <= (N - 1) * maxA) {
        add_edge(i, j, i, j + change[i][0], -change[i][0], change[i][1], node);
      } else {
        add_edge(i, j, i, maxA * (N - 1), -change[i][0], change[i][1], node);
      }
    }
  }
  dijkstra(0, S, node, dis);
  ll ans = INF;
  for (ll i = 1; i < N; i++) {
    ans = INF;
    for (ll j = 0; j < maxA * (N - 1) + 1; j++) {
      ans = min(ans, dis[i][j]);
    }
    cout << ans << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

/*#include<iostream>
#include<bits/stdc++.h>
#include<queue>
#include<string>
#include<tuple>*/
#include <vector>
using namespace std;
struct edge {
  int to, cost, time, rev;
};
using Graph = vector<vector<edge>>;
#define p make_pair
#define INF 1000000007
#define get(a, b) get<a>(b)
#define t make_tuple

void add_edge(int from, int to, int cost, int time, Graph &graph) {
  graph[from].push_back((edge){to, cost, time, (int)graph[to].size()});
  graph[from].push_back((edge){from, cost, time, (int)graph[from].size() - 1});
}

void dijkstra(int s, int S, Graph graph, vector<pair<int, int>> change,
              vector<pair<int, int>> &dis) {
  int n = graph.size();
  for (int i = 0; i < n; i++)
    dis[i] = p(INF, 0); // 1はかかる時間,２は所持銀貨数
  vector<pair<int, int>> prev(n, p(-1, -1));
  dis[s].second = S;
  dis[s].first = 0;
  prev[s] = p(s, -1);
  priority_queue<tuple<int, int, int>, vector<tuple<int, int, int>>,
                 greater<tuple<int, int, int>>>
      que;
  que.push(t(dis[s].first, dis[s].second, s));
  int v, from, to, ginka, m;
  while (!que.empty()) {
    v = get(2, que.top());
    que.pop();
    for (int i = 0; i < graph[v].size(); i++) {
      edge &e = graph[v][i];
      if (dis[v].second >= e.cost) {
        if (dis[e.to].first > dis[v].first + e.time) {
          dis[e.to].first = dis[v].first + e.time;
          dis[e.to].second = dis[v].second - e.cost;
          prev[e.to] = p(v, i);
          que.push(t(dis[e.to].first, dis[e.to].second, e.to));
        }
      } else {
        from = -1;
        to = v;
        m = INF;
        while (from != s) {
          from = prev[to].first;
          if (m > ((e.cost - dis[v].second) / change[to].first +
                   ((e.cost - dis[v].second) % change[to].first == 0 ? 0 : 1)) *
                      change[to].second) {
            m = ((e.cost - dis[v].second) / change[to].first +
                 ((e.cost - dis[v].second) % change[to].first == 0 ? 0 : 1)) *
                change[to].second;
            ginka =
                dis[v].second +
                ((e.cost - dis[v].second) / change[to].first +
                 ((e.cost - dis[v].second) % change[to].first == 0 ? 0 : 1)) *
                    change[to].first;
          }
          to = from;
        }
        if (m > ((e.cost - dis[v].second) / change[to].first +
                 ((e.cost - dis[v].second) % change[to].first == 0 ? 0 : 1)) *
                    change[to].second) {
          m = ((e.cost - dis[v].second) / change[to].first +
               ((e.cost - dis[v].second) % change[to].first == 0 ? 0 : 1)) *
              change[to].second;
          ginka = dis[v].second +
                  ((e.cost - dis[v].second) / change[to].first +
                   ((e.cost - dis[v].second) % change[to].first == 0 ? 0 : 1)) *
                      change[to].first;
        }
        if (dis[e.to].first > dis[v].first + e.time + m) {
          dis[e.to].first = dis[v].first + e.time + m;
          dis[e.to].second = ginka - e.cost;
          prev[e.to] = p(v, i);
          que.push(make_tuple(dis[e.to].first, dis[e.to].second, e.to));
        }
      }
    }
  }
}

int main() {
  int N, M, S;
  cin >> N >> M >> S;
  int u, v, a, b;
  Graph graph(N, vector<edge>());
  vector<vector<pair<int, int>>> graph2(N,
                                        vector<pair<int, int>>(N, p(INF, INF)));
  vector<pair<int, int>> dis(N);
  vector<pair<int, int>> change(N);
  for (int i = 0; i < M; i++) {
    cin >> u >> v >> a >> b;
    u--;
    v--;
    graph2[u][v] = p(a, b);
    graph2[v][u] = p(a, b);
  }
  for (int i = 0; i < N; i++)
    graph2[i][i] = p(0, 0);
  for (int k = 0; k < N; k++) {
    for (int i = 0; i < N; i++) {
      for (int j = 0; j < N; j++) {
        if (graph2[i][j].second >= graph2[i][k].second + graph2[k][j].second) {
          graph2[i][j].first = graph2[i][k].first + graph2[k][j].first;
          graph2[i][j].second = graph2[i][k].second + graph2[k][j].second;
        }
      }
    }
  }
  for (int i = 0; i < N; i++) {
    for (int j = i + 1; j < N; j++) {
      add_edge(i, j, graph2[i][j].first, graph2[i][j].second, graph);
    }
  }
  for (int i = 0; i < N; i++) {
    cin >> a >> b;
    change[i] = p(a, b);
  }
  dijkstra(0, S, graph, change, dis);
  for (int i = 1; i < N; i++)
    cout << dis[i].first << endl;
  return 0;
}