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

// 2009à\\ID £UI¬x
#include <cstring>
#include <iostream>
#include <queue>
#include <vector>

using namespace std;

typedef vector<vector<int>> graph;

class Node {
public:
  // p : »ÝÊu
  // v : »ÝÌXs[h
  // prev : OÉ¢½XÔ
  // cost : ±±ÜÅÌ£
  int p, v, prev;
  double cost;
  Node(int p, int v, int prev, double cost)
      : p(p), v(v), prev(prev), cost(cost) {}
  // priority_queueÅ¸\\[gÉ·éÌªÊ|ÈÌÅCsðtÉè`µÄµÜ¤
  bool operator<(const Node &nd) const { return cost > nd.cost; }
};

int main() {
  int n, m, s, g;
  while (cin >> n >> m) {
    if (!(n || m))
      break;
    cin >> s >> g;
    graph gp(n);
    // £sñÆC§À¬xsñ(?)
    int dist[30][30];
    int limit[30][30];
    // óÔ(Êu, ¬x,
    // OÌÊu)ª`FbNÏÝ©ð`FbN·éD
    bool visit[30][31][30];
    double len[30][31][30];
    memset(visit, false, sizeof(visit));
    for (int i = 0; i < m; i++) {
      int x, y, d, c;
      cin >> x >> y >> d >> c;
      gp[x - 1].push_back(y - 1);
      gp[y - 1].push_back(x - 1);
      dist[x - 1][y - 1] = d, dist[y - 1][x - 1] = d;
      limit[x - 1][y - 1] = c, limit[y - 1][x - 1] = c;
    }
    for (int i = 0; i < n; i++)
      for (int j = 0; j <= 30; j++)
        for (int k = 0; k < n; k++)
          len[i][j][k] = 1e15;
    priority_queue<Node> qu;
    qu.push(Node(s - 1, 0, s - 1, 0.0));
    double ans = -1.0;
    // _CLXg@ÅÅZoH·ðßé
    while (!qu.empty()) {
      Node nd = qu.top();
      qu.pop();
      int p = nd.p, v = nd.v, prev = nd.prev;
      // `FbNÏÝÌóÔÈçcontinue
      if (visit[p][v][prev])
        continue;
      visit[p][v][prev] = true;
      // S[óÔ
      if (p == g - 1 && v == 1) {
        ans = nd.cost;
        break;
      }
      for (int i = 0; i < gp[p].size(); i++) {
        int next = gp[p][i];
        // U^[ÍÖ~
        if (next == prev)
          continue;
        // ¬xðÆµ½èã°½è
        for (int j = -1; j <= 1; j++) {
          int nv = v + j;
          if (nv <= 0 || limit[p][next] < nv)
            continue;
          if (len[next][nv][p] - 1e-8 > nd.cost + (double)dist[p][next] / nv) {
            len[next][nv][p] = nd.cost + (double)dist[p][next] / nv;
            qu.push(Node(next, nv, p, len[next][nv][p]));
          }
        }
      }
    }
    if (ans < 0.0)
      cout << "unreachable" << endl;
    else
      printf("%.5f\\n", ans);
  }
}

Error: TLE

Fixed submission:

#include <iostream>
#include <queue>
#include <string.h>
#include <vector>

using namespace std;

typedef vector<vector<int>> graph;

class Node {
public:
  int p, v, prev;
  double cost;
  Node(int p, int v, int prev, double cost)
      : p(p), v(v), prev(prev), cost(cost) {}
  bool operator<(const Node &nd) const { return cost > nd.cost; }
};

int main() {
  int n, m, s, g;
  while (cin >> n >> m) {
    if (!(n || m))
      break;
    cin >> s >> g;
    graph gp(n);
    int dist[30][30];
    int limit[30][30];
    bool visit[30][31][30];
    memset(visit, false, sizeof(visit));
    for (int i = 0; i < m; i++) {
      int x, y, d, c;
      cin >> x >> y >> d >> c;
      gp[x - 1].push_back(y - 1);
      gp[y - 1].push_back(x - 1);
      dist[x - 1][y - 1] = d, dist[y - 1][x - 1] = d;
      limit[x - 1][y - 1] = c, limit[y - 1][x - 1] = c;
    }
    priority_queue<Node> qu;
    qu.push(Node(s - 1, 0, s - 1, 0.0));
    double ans = -1.0;
    while (!qu.empty()) {
      Node nd = qu.top();
      qu.pop();
      int p = nd.p, v = nd.v, prev = nd.prev;
      if (visit[p][v][prev])
        continue;
      visit[p][v][prev] = true;
      if (p == g - 1 && v == 1) {
        ans = nd.cost;
        break;
      }
      for (int i = 0; i < gp[p].size(); i++) {
        int next = gp[p][i];
        if (next == prev)
          continue;
        for (int j = -1; j <= 1; j++) {
          int nv = v + j;
          if (nv <= 0 || limit[p][next] < nv)
            continue;
          qu.push(Node(next, nv, p, nd.cost + (double)dist[p][next] / nv));
        }
      }
    }
    if (ans < 0.0)
      cout << "unreachable" << endl;
    else
      printf("%.5f\\n", ans);
  }
}