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

#include <iostream>
#include <queue>
#include <vector>
#define rep(i, n) for (int i = 0; i < n; i++)
using namespace std;
struct Node {
  double time;
  int cur, prev, v;
};
bool operator<(const Node &l, const Node &r) { return l.time > r.time; }
struct Edge {
  int next, d, lim;
};
int main() {
  int n, m, s, g;
NEXT:
  while (cin >> n >> m, n) {
    cin >> s >> g, s--, g--;
    vector<vector<Edge>> e(n);
    rep(i, m) {
      int x, y, d, c;
      cin >> x >> y >> d >> c, x--, y--;
      Edge t;
      t.d = d, t.lim = c;
      t.next = y, e[x].push_back(t);
      t.next = x, e[y].push_back(t);
    }
    priority_queue<Node> Q;
    double C[30][30][31];
    rep(i, 30) rep(j, 30) rep(k, 31) C[i][j][k] = 1e99;
    Node init, cnode, nnode;
    rep(i, e[s].size()) {
      init.time = e[s][i].d, init.cur = e[s][i].next, init.prev = s, init.v = 1;
      Q.push(init);
      C[init.cur][s][1] = e[s][i].d;
    }
    while (!Q.empty()) {
      nnode = cnode = Q.top();
      Q.pop();
      if (cnode.cur == g && cnode.v == 1) {
        cout << cnode.time << endl;
        goto NEXT;
      }
      int c = cnode.cur, cv = cnode.v;
      nnode.prev = c;
      rep(i, e[c].size()) if (e[c][i].next != cnode.prev) for (
          int nv = cv - 1; nv <= cv + 1;
          nv++) if (0 < nv &&
                    nv <= e[c][i].lim) if (C[e[c][i].next][c][nv] >
                                           cnode.time + 1. * e[c][i].d / nv) {
        nnode.time = cnode.time + 1. * e[c][i].d / nv, nnode.v = nv,
        nnode.cur = e[c][i].next;
        C[e[c][i].next][c][nv] = nnode.time, Q.push(nnode);
      }
    }
    cout << "unreachable" << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <cstdio>
#include <queue>
#define rep(i, n) for (int i = 0; i < n; i++)
#define INF 1e9
using namespace std;
double cost[30][30][31];
int d[30][30], c[30][30], v[30][30][31];
class S {
public:
  double cc;
  int c, p, v;
  S(double cc, int c, int p, int v) : cc(cc), c(c), p(p), v(v) {}
  bool operator<(const S &a) const { return cc > a.cc; }
};
int main() {
  int n, m, s, g, x, y, a, b;
  double nc;
  while (scanf("%d%d", &n, &m), n) {
    scanf("%d%d", &s, &g), s--, g--;
    rep(i, n) rep(j, n) {
      rep(k, 31) cost[i][j][k] = INF, v[i][j][k] = 0;
      d[i][j] = c[i][j] = 0;
    }
    rep(i, m) scanf("%d%d%d%d", &x, &y, &a, &b), x--, y--,
        d[x][y] = d[y][x] = a, c[x][y] = c[y][x] = b;
    priority_queue<S> F;
    F.push(S(0, s, s, 0));
    cost[s][s][0] = 0;
    while (!F.empty()) {
      S cs = F.top();
      F.pop();
      v[cs.c][cs.p][cs.v] = 1;
      if (cs.c == g && cs.v == 1) {
        printf("%.5f\\n", cs.cc);
        goto END;
      }
      rep(i, n) if (i != cs.p &&
                    d[cs.c][i]) for (int dv = -1; dv < 2;
                                     dv++) if (!v[i][cs.c][dv + cs.v] &&
                                               0 < dv + cs.v &&
                                               dv + cs.v <= c[cs.c][i]) {
        nc = cost[cs.c][cs.p][cs.v] + 1. * d[cs.c][i] / (dv + cs.v);
        if (cost[i][cs.c][dv + cs.v] > nc)
          cost[i][cs.c][dv + cs.v] = nc, F.push(S(nc, i, cs.c, dv + cs.v));
      }
    }
    printf("unreachable\\n");
  END:;
  }
  return 0;
}