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

#include <algorithm>
#include <functional>
#include <iomanip>
#include <iostream>
#include <queue>
#include <tuple>
#include <vector>
using namespace std;

#define MAX_N 110
#define INF 999999999.99

int N, M, S, G, a, b, c, d;
double X[MAX_N][MAX_N][2];
double dist[MAX_N][MAX_N][MAX_N];

priority_queue<tuple<double, int, int, int>,
               vector<tuple<double, int, int, int>>,
               greater<tuple<double, int, int, int>>>
    Q;

double dijkstra() {
  dist[S][0][0] = 0;
  Q.push(make_tuple(0.0, S, 0, 0));

  while (!Q.empty()) {
    tuple<double, int, int, int> tup = Q.top();
    Q.pop();
    double a1 = get<0>(tup);
    int a2 = get<1>(tup);
    int a3 = get<2>(tup);
    int a4 = get<3>(tup);

    for (int i = 1; i <= N; i++) {
      if (i == a4) {
        continue;
      }
      // X-1.
      if (a3 >= 1 && X[a2][i][1] >= a3 - 1) {
        double jikan = X[a2][i][0] / (a3 - 1);

        if (dist[i][a3 - 1][a2] > jikan + a1) {
          dist[i][a3 - 1][a2] = jikan + a1;
          Q.push(make_tuple(dist[i][a3 - 1][a2], i, a3 - 1, a2));
        }
      }
      // X.
      if (X[a2][i][1] >= a3) {
        double jikan = X[a2][i][0] / a3;

        if (dist[i][a3][a2] > jikan + a1) {
          dist[i][a3][a2] = jikan + a1;
          Q.push(make_tuple(dist[i][a3][a2], i, a3, a2));
        }
      }
      // X+1.
      if (X[a2][i][1] >= a3 + 1) {
        double jikan = X[a2][i][0] / (a3 + 1);

        if (dist[i][a3 + 1][a2] > jikan + a1) {
          dist[i][a3 + 1][a2] = jikan + a1;
          Q.push(make_tuple(dist[i][a3 + 1][a2], i, a3 + 1, a2));
        }
      }
    }
  }
  double RES = INF;
  for (int i = 0; i < MAX_N; i++) {
    RES = min(RES, dist[G][1][i]);
  }
  return RES;
}

int main() {
  while (true) {
    cin >> N >> M;
    if (N == 0 && M == 0) {
      break;
    }
    cin >> S >> G;
    for (int i = 0; i < MAX_N; i++) {
      for (int j = 0; j < MAX_N; j++) {
        X[i][j][0] = INF;
        X[i][j][1] = 0.0;
        for (int k = 0; k < MAX_N; k++) {
          dist[i][j][k] = INF;
        }
      }
    }
    for (int i = 0; i < M; i++) {
      cin >> a >> b >> c >> d;
      X[a][b][0] = c;
      X[b][a][0] = c;
      X[a][b][1] = d;
      X[b][a][1] = d;
    }
    double res1 = dijkstra();
    double res;
    res = res1;
    if (res > INF / 2) {
      cout << "unreachable" << endl;
    } else {
      cout << fixed << setprecision(15) << res << endl;
    }
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <iomanip>
#include <iostream>
using namespace std;

#define INF 1145141919.810

int n, m, s, g;
double x[50][50][2];
int a, b, c, d;

double dp[50][50];
double res;

double solve(int p, int st, int go) {
  dp[st][0] = 0;
  for (int i = 1; i <= p * 100; i++) {
    for (int j = 1; j <= p; j++) {
      for (int k = 0; k <= 30; k++) {
        if (dp[j][k] < INF) {
          for (int l = 0; l <= p; l++) {
            if (x[j][l][0] < 100000) {
              // v-1.
              if (k - 1 >= 1 && k - 1 <= x[j][l][1]) {
                dp[l][k - 1] =
                    min(dp[l][k - 1], dp[j][k] + 1.0 * x[j][l][0] / (k - 1));
              }
              // v.
              if (k >= 1 && k <= x[j][l][1]) {
                dp[l][k] = min(dp[l][k], dp[j][k] + 1.0 * x[j][l][0] / k);
              }
              // v-1.
              if (k + 1 >= 1 && k + 1 <= x[j][l][1]) {
                dp[l][k + 1] =
                    min(dp[l][k + 1], dp[j][k] + 1.0 * x[j][l][0] / (k + 1));
              }
            }
          }
        }
      }
    }
  }
  return dp[go][1];
}

int main() {
  while (true) {
    for (int i = 0; i < 50; i++) {
      for (int j = 0; j < 50; j++) {
        dp[i][j] = INF;
        x[i][j][0] = 10000000;
        x[i][j][1] = 0;
      }
    }
    cin >> n >> m;
    if (n == 0 && m == 0) {
      break;
    }
    cin >> s >> g;
    for (int i = 0; i < m; i++) {
      cin >> a >> b >> c >> d;
      x[a][b][0] = c;
      x[a][b][1] = d;
      x[b][a][0] = c;
      x[b][a][1] = d;
    }
    res = solve(n, s, g);
    if (res > 1000000.00) {
      cout << "unreachable" << endl;
    } else {
      cout << fixed << setprecision(15) << res << endl;
    }
  }
}