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

#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>

using namespace std;

#define FOR(i, k, n) for (int i = (k); i < (int)n; ++i)
#define REP(i, n) FOR(i, 0, n)
#define FORIT(i, c)                                                            \\
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)

template <class T> void debug(T begin, T end) {
  for (T i = begin; i != end; ++i)
    cout << *i << " ";
  cout << endl;
}

typedef long long ll;
const int INF = 100000000;
const double EPS = 1e-8;
const int MOD = 1000000007;
struct S {
  double t;
  int v;
  int p;
  int from;
  S() {}
  S(double t, int v, int p, int from) : t(t), v(v), p(p), from(from) {}
};
struct edge {
  int to, dist, lim;
  edge(int to, int dist, int lim) : to(to), dist(dist), lim(lim) {}
};
typedef vector<edge> edges;
bool operator<(const S &s, const S &t) { return s.t > t.t; }
int main() {
  int n, m, s, g;
  while (cin >> n >> m >> s >> g, n) {
    s--;
    g--;
    vector<edges> graph(n);
    REP(i, m) {
      int x, y, d, c;
      cin >> x >> y >> d >> c;
      x--;
      y--;
      graph[x].push_back(edge(y, d, c));
      graph[y].push_back(edge(x, d, c));
    }
    priority_queue<S> que;
    FORIT(it, graph[s]) { que.push(S(it->dist, 1, it->to, s)); }
    bool used[40][40][40] = {};
    double ans = -1;
    while (!que.empty()) {
      S s = que.top();
      que.pop();
      // printf("quesize:%d time:%lf speed:%d point:%d\\n",que.size(),
      // s.t,s.v,s.p);
      if (s.p == g && s.v == 1) {
        ans = s.t;
        break;
      }
      for (int nv = s.v - 1; nv <= s.v + 1; nv++)
        if (nv > 0) {
          FORIT(it, graph[s.p]) if (it->lim >= nv && it->to != s.from) {
            if (used[nv][it->to][s.p])
              continue;
            used[nv][it->to][s.p] = true;
            que.push(S(s.t + (double)it->dist / nv, nv, it->to, s.p));
          }
        }
    }
    if (ans != -1)
      printf("%.4lf\\n", ans);
    else
      cout << "unreachable" << endl;
  }

  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>

using namespace std;

#define FOR(i, k, n) for (int i = (k); i < (int)n; ++i)
#define REP(i, n) FOR(i, 0, n)
#define FORIT(i, c)                                                            \\
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)

template <class T> void debug(T begin, T end) {
  for (T i = begin; i != end; ++i)
    cout << *i << " ";
  cout << endl;
}

typedef long long ll;
const int INF = 100000000;
const double EPS = 1e-8;
const int MOD = 1000000007;
struct S {
  double t;
  int v;
  int p;
  int from;
  S() {}
  S(double t, int v, int p, int from) : t(t), v(v), p(p), from(from) {}
};
struct edge {
  int to, dist, lim;
  edge(int to, int dist, int lim) : to(to), dist(dist), lim(lim) {}
};
typedef vector<edge> edges;
bool operator<(const S &s, const S &t) { return s.t > t.t; }
int main() {
  int n, m, s, g;
  while (cin >> n >> m >> s >> g, n) {
    s--;
    g--;
    vector<edges> graph(n);
    REP(i, m) {
      int x, y, d, c;
      cin >> x >> y >> d >> c;
      x--;
      y--;
      graph[x].push_back(edge(y, d, c));
      graph[y].push_back(edge(x, d, c));
    }
    priority_queue<S> que;
    FORIT(it, graph[s]) { que.push(S(it->dist, 1, it->to, s)); }
    bool used[40][40][40] = {};
    double ans = -1;
    while (!que.empty()) {
      S s = que.top();
      que.pop();
      // printf("quesize:%d time:%lf speed:%d point:%d\\n",que.size(),
      // s.t,s.v,s.p);
      if (s.p == g && s.v == 1) {
        ans = s.t;
        break;
      }
      if (used[s.v][s.p][s.from])
        continue;
      used[s.v][s.p][s.from] = true;
      for (int nv = s.v - 1; nv <= s.v + 1; nv++)
        if (nv > 0) {
          FORIT(it, graph[s.p]) if (it->lim >= nv && it->to != s.from) {
            que.push(S(s.t + (double)it->dist / nv, nv, it->to, s.p));
          }
        }
    }
    if (ans != -1)
      printf("%.4lf\\n", ans);
    else
      cout << "unreachable" << endl;
  }

  return 0;
}