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

#include "bits/stdc++.h"
using namespace std;

typedef long long ll;
#define rep(i, n) for (ll i = 0; i < (ll)(n); i++)
#define all(a) (a).begin(), (a).end()
#define pb push_back
#define INF 999999999

typedef pair<double, tuple<int, int, int>> pit3;
typedef pair<int, tuple<int, int>> pit2;

int n, m;

double d[32][32][32];

vector<pit2> pass[32];

double dijk(int s, int g) {
  priority_queue<pit3, vector<pit3>, greater<pit3>> que;
  rep(i, 32) rep(j, 32) rep(k, 32) d[i][j][k] = INF;
  d[s][1][31] = 0;
  que.push(pit3(0.0, make_tuple(s, 1, 31)));

  bool f = false;
  while (que.size()) {
    //        cout<<que.size()<<endl;
    pit3 p = que.top();
    que.pop();

    int v = get<0>(p.second);
    int w = get<1>(p.second);
    int x = get<2>(p.second);
    if (d[v][w][x] < p.first)
      continue;
    rep(i, pass[v].size()) {
      pit2 e = pass[v][i];
      if (x == e.first)
        continue;
      if (w <= get<1>(e.second) &&
          d[e.first][w][v] > d[v][w][x] + (double)(get<0>(e.second)) / w) {
        d[e.first][w][v] = d[v][w][x] + (double)(get<0>(e.second)) / w;
        que.push(pit3(d[e.first][w][v], make_tuple(e.first, w, v)));
        //                cout<<"d["<<e.first<<"]["<<w<<"]["<<v<<"] =
        //                "<<d[e.first][w][v]<<endl;
      }
      if (w + 1 <= get<1>(e.second) &&
          d[e.first][w + 1][v] >
              d[v][w][x] + (double)(get<0>(e.second)) / (w + 1) &&
          f) {
        d[e.first][w + 1][v] =
            d[v][w][x] + (double)(get<0>(e.second)) / (w + 1);
        que.push(pit3(d[e.first][w + 1][v], make_tuple(e.first, w + 1, v)));
        //                cout<<"d["<<e.first<<"]["<<w+1<<"]["<<v<<"] =
        //                "<<d[e.first][w+1][v]<<endl;
      }
      if (w - 1 <= get<1>(e.second) && w - 1 > 0 &&
          d[e.first][w - 1][v] >
              d[v][w][x] + (double)(get<0>(e.second)) / (w - 1) &&
          f) {
        d[e.first][w - 1][v] =
            d[v][w][x] + (double)(get<0>(e.second)) / (w - 1);
        que.push(pit3(d[e.first][w - 1][v], make_tuple(e.first, w - 1, v)));
        //                cout<<"d["<<e.first<<"]["<<w-1<<"]["<<v<<"] =
        //                "<<d[e.first][w-1][v]<<endl;
      }
    }
    f = true;
  }
  double ret = INF;
  rep(i, 32) { ret = min(ret, d[g][1][i]); }
  return ret;
}

int main() {
  int s, g;

  while (cin >> n >> m) {
    if (n == 0 && m == 0)
      break;

    rep(i, 32) pass[i].clear();
    cin >> s >> g;
    s--, g--;
    rep(i, m) {
      int x, y, D, c;
      cin >> x >> y >> D >> c;
      x--, y--;
      pass[x].pb(pit2(y, make_tuple(D, c)));
      pass[y].pb(pit2(x, make_tuple(D, c)));
    }
    double res = dijk(s, g);
    if (res == INF)
      cout << "unreachable" << endl;
    else
      printf("%.10lf\\n", res);
  }
}

Error: TLE

Fixed submission:

#include "bits/stdc++.h"
using namespace std;

typedef long long ll;
#define rep(i, n) for (ll i = 0; i < (ll)(n); i++)
#define all(a) (a).begin(), (a).end()
#define pb push_back
#define INF 999999999

int n, m;
pair<int, int> pass[32][32];

double d[32][32][32];
bool used[32][32][32];

double dijk(int s, int g) {
  bool f = false;
  rep(i, 32) rep(j, 32) rep(k, 32) d[i][j][k] = INF;
  rep(i, 32) rep(j, 32) rep(k, 32) used[i][j][k] = false;
  d[s][1][31] = 0;

  while (1) {
    int v = -1, w = -1, x = -1;
    rep(u, n) {
      rep(i, 32) {
        rep(j, 32) {
          if (!used[u][i][j] && (v == -1 || d[u][i][j] < d[v][w][x]))
            v = u, w = i, x = j;
        }
      }
    }
    if (v == -1)
      break;

    used[v][w][x] = true;
    rep(u, n) {
      if (pass[v][u].first == INF)
        continue;
      d[u][w][v] = min(d[u][w][v], d[v][w][x] + ((double)pass[v][u].first / w));

      if (w + 1 <= pass[v][u].second && f)
        d[u][w + 1][v] = min(d[u][w + 1][v],
                             d[v][w][x] + ((double)pass[v][u].first / (w + 1)));

      if (w - 1 >= 0 && f)
        d[u][w - 1][v] = min(d[u][w - 1][v],
                             d[v][w][x] + ((double)pass[v][u].first / (w - 1)));
    }
    f = true;
  }
  double ret = INF;
  rep(i, 32) { ret = min(ret, d[g][1][i]); }
  return ret;
}

int main() {
  int s, g;

  while (cin >> n >> m) {
    if (n == 0 && m == 0)
      break;

    rep(i, 32) rep(j, 32) pass[i][j] = make_pair(INF, -1);
    cin >> s >> g;
    s--, g--;
    rep(i, m) {
      int x, y, d, c;
      cin >> x >> y >> d >> c;
      x--, y--;
      pass[x][y] = pass[y][x] = make_pair(d, c);
    }
    double res = dijk(s, g);
    if (res == INF)
      cout << "unreachable" << endl;
    else
      printf("%.10lf\\n", res);
  }
}