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

#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
using namespace std;

struct NODE {
  int from, to, speed;
  double cost;
  NODE(int from, int to, int speed, double cost)
      : from(from), to(to), speed(speed), cost(cost) {}
};
bool operator<(const NODE &a, const NODE &b) { return a.cost > b.cost; }

vector<vector<NODE>> G;
bool done[32][32][1000] = {};
bool done2[32];

bool dfs(int x, int y) {
  if (x == y)
    return true;
  if (done2[x])
    return false;
  done2[x] = true;
  for (int i = 0; i < G[x].size(); i++)
    if (dfs(G[x][i].to, y))
      return true;
  return false;
}
int main() {
  int n, m;
  while (cin >> n >> m && n) {
    memset(done, 0, sizeof(done));
    memset(done2, 0, sizeof(done2));
    int s, g;
    cin >> s >> g;
    s--, g--;
    G.clear();
    G.resize(n);
    for (int i = 0; i < m; i++) {
      int a, b, c, d;
      cin >> a >> b >> d >> c;
      a--, b--;
      G[a].push_back(NODE(a, b, c, d));
      G[b].push_back(NODE(b, a, c, d));
      // cout << a << " " << b << " " << c << " " << d << endl;
    }
    if (!dfs(s, g)) {
      cout << "unreachable" << endl;
      continue;
    }
    priority_queue<NODE> Q;

    Q.push(NODE(n, s, 0, 0));
    while (Q.size()) {
      NODE q = Q.top();
      Q.pop();
      if (q.speed >= 1000)
        continue;
      if (done[q.from][q.to][q.speed])
        continue;
      else
        done[q.from][q.to][q.speed] = true;
      if (q.to == g && q.speed == 1) {
        printf("%.10lf\\n", q.cost);
        goto exit;
      }
      for (int i = 0; i < G[q.to].size(); i++) {
        if (q.speed + 0 > 0 && q.speed + 0 <= G[q.to][i].speed &&
            q.from != G[q.to][i].to)
          Q.push(NODE(q.to, G[q.to][i].to, q.speed + 0,
                      q.cost + G[q.to][i].cost / (q.speed + 0)));
        if (q.speed + 1 > 0 && q.speed + 1 <= G[q.to][i].speed &&
            q.from != G[q.to][i].to)
          Q.push(NODE(q.to, G[q.to][i].to, q.speed + 1,
                      q.cost + G[q.to][i].cost / (q.speed + 1)));
        if (q.speed - 1 > 0 && q.speed - 1 <= G[q.to][i].speed &&
            q.from != G[q.to][i].to)
          Q.push(NODE(q.to, G[q.to][i].to, q.speed - 1,
                      q.cost + G[q.to][i].cost / (q.speed - 1)));
      }
    }
    cout << "unreachable" << endl;
  exit:;
  }
}

Error: TLE

Fixed submission:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
using namespace std;

struct NODE {
  int from, to, speed;
  double cost;
  NODE(int from, int to, int speed, double cost)
      : from(from), to(to), speed(speed), cost(cost) {}
};
bool operator<(const NODE &a, const NODE &b) { return a.cost > b.cost; }

vector<vector<NODE>> G;
bool done[32][32][50] = {};
int main() {
  int n, m;
  while (cin >> n >> m && n) {
    memset(done, 0, sizeof(done));
    int s, g;
    cin >> s >> g;
    s--, g--;
    G.clear();
    G.resize(n);
    for (int i = 0; i < m; i++) {
      int a, b, c, d;
      cin >> a >> b >> d >> c;
      a--, b--;
      G[a].push_back(NODE(a, b, c, d));
      G[b].push_back(NODE(b, a, c, d));
      // cout << a << " " << b << " " << c << " " << d << endl;
    }
    priority_queue<NODE> Q;

    Q.push(NODE(n, s, 0, 0));
    while (Q.size()) {
      NODE q = Q.top();
      Q.pop();
      if (q.speed >= 50)
        continue;
      if (done[q.from][q.to][q.speed])
        continue;
      else
        done[q.from][q.to][q.speed] = true;
      if (q.to == g && q.speed == 1) {
        printf("%.10lf\\n", q.cost);
        goto exit;
      }
      for (int i = 0; i < G[q.to].size(); i++) {
        if (q.speed + 0 > 0 && q.speed + 0 <= G[q.to][i].speed &&
            q.from != G[q.to][i].to)
          Q.push(NODE(q.to, G[q.to][i].to, q.speed + 0,
                      q.cost + G[q.to][i].cost / (q.speed + 0)));
        if (q.speed + 1 > 0 && q.speed + 1 <= G[q.to][i].speed &&
            q.from != G[q.to][i].to)
          Q.push(NODE(q.to, G[q.to][i].to, q.speed + 1,
                      q.cost + G[q.to][i].cost / (q.speed + 1)));
        if (q.speed - 1 > 0 && q.speed - 1 <= G[q.to][i].speed &&
            q.from != G[q.to][i].to)
          Q.push(NODE(q.to, G[q.to][i].to, q.speed - 1,
                      q.cost + G[q.to][i].cost / (q.speed - 1)));
      }
    }
    cout << "unreachable" << endl;
  exit:;
  }
}