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

/*
最初にスタート地点からでるときはスピードが１でなければならないのを忘れてた
ゴールは到着したら即終了というわけではない
というかゴールにスピード１以外で到着しても良い（でもゴールしたいときは１でないといけない）
*/

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <deque>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <vector>
#define F first
#define S second
#define MAX_N 32
#define MAX_D 32
#define INF (1 << 28)
#define REP(i, s, n) for (int i = s; i < n; i++)
#define rep(i, n) REP(i, 0, n)

using namespace std;
typedef pair<double, double> P;
typedef pair<int, P> iP;
typedef pair<int, int> iiP;
typedef pair<iiP, P> PP;
typedef vector<vector<iP>> VViP;
int n, m, s, g;
VViP G;
double mincost[MAX_N][MAX_N][MAX_D]; // mincost[from][to][speed]
int sp[] = {-1, 0, +1};

void dijkstra() {

  deque<PP> deq; // iiPP(iiP(now,pre),P(cost,speed))

  deq.push_front(PP(iiP(s, s), P(0, 1)));

  mincost[s][s][1] = 0;
  double ans = INF;

  while (!deq.empty()) {
    PP p = deq.front();
    deq.pop_front();
    int now, pre;
    double cost, speed;
    now = p.F.F, pre = p.F.S;
    cost = p.S.F, speed = p.S.S;

    if (cost >= ans)
      continue;

    if (now == g && speed == 1) {
      ans = min(ans, cost);
      continue;
    }

    for (int i = 0; i < G[now].size(); i++) {
      iP ip = G[now][i]; // VViP -> iP(to,P(distance,limit))
      int to = ip.F;
      double dis, lim;
      dis = ip.S.F, lim = ip.S.S;
      if (pre == to)
        continue;

      for (int j = 0; j < 3; j++) {
        double new_speed = speed + sp[j];
        if (new_speed <= 0 || new_speed > lim)
          continue;

        if (now == s && pre == s && new_speed != 1)
          continue;

        if (mincost[now][to][(int)new_speed] > cost + (double)dis / new_speed) {
          mincost[now][to][(int)new_speed] = cost + (double)dis / new_speed;
          if (mincost[now][to][(int)new_speed] < deq.front().S.F)
            deq.push_front(PP(iiP(to, now),
                              P(mincost[now][to][(int)new_speed], new_speed)));
          else
            deq.push_back(PP(iiP(to, now),
                             P(mincost[now][to][(int)new_speed], new_speed)));
        }
      }
    }
  }

  if (ans == INF)
    cout << "unreachable" << endl;
  else
    cout << setiosflags(ios::fixed) << setprecision(5) << ans << endl;
}

int main() {

  while (true) {
    cin >> n >> m;
    if (n + m == 0)
      break;
    G.clear();
    G.resize(n + 1);
    rep(i, n + 1) rep(j, n + 1) rep(k, 31) mincost[i][j][k] = INF;

    cin >> s >> g;
    rep(i, m) {
      int x, y;
      double d, c;
      cin >> x >> y >> d >> c;
      G[x].push_back(iP(y, P(d, c)));
      G[y].push_back(iP(x, P(d, c)));
    }

    dijkstra();
  }
  return 0;
}

Error: TLE

Fixed submission:

/*
最初にスタート地点からでるときはスピードが１でなければならないのを忘れてた
ゴールは到着したら即終了というわけではない
というかゴールにスピード１以外で到着しても良い（でもゴールしたいときは１でないといけない）
*/

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <deque>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <vector>
#define F first
#define S second
#define MAX_N 32
#define MAX_D 32
#define INF (1 << 28)
#define REP(i, s, n) for (int i = s; i < n; i++)
#define rep(i, n) REP(i, 0, n)

using namespace std;
typedef pair<double, double> P;
typedef pair<int, P> iP;
typedef pair<int, int> iiP;
typedef pair<iiP, P> PP;
typedef vector<vector<iP>> VViP;
int n, m, s, g;
VViP G;
double mincost[MAX_N][MAX_N][MAX_D]; // mincost[from][to][speed]
int sp[] = {-1, 0, +1};

void dijkstra() {

  queue<PP> deq; // iiPP(iiP(now,pre),P(cost,speed))

  deq.push(PP(iiP(s, s), P(0, 1)));

  mincost[s][s][1] = 0;
  double ans = INF;

  while (!deq.empty()) {
    PP p = deq.front();
    deq.pop();
    int now, pre;
    double cost, speed;
    now = p.F.F, pre = p.F.S;
    cost = p.S.F, speed = p.S.S;

    if (cost >= ans)
      continue;

    if (now == g && speed == 1) {
      ans = min(ans, cost);
      continue;
    }

    for (int i = 0; i < G[now].size(); i++) {
      iP ip = G[now][i]; // VViP -> iP(to,P(distance,limit))
      int to = ip.F;
      double dis, lim;
      dis = ip.S.F, lim = ip.S.S;
      if (pre == to)
        continue;

      for (int j = 0; j < 3; j++) {
        double new_speed = speed + sp[j];
        if (new_speed <= 0 || new_speed > lim)
          continue;

        if (now == s && pre == s && new_speed != 1)
          continue;

        if (mincost[now][to][(int)new_speed] > cost + (double)dis / new_speed) {
          mincost[now][to][(int)new_speed] = cost + (double)dis / new_speed;
          deq.push(
              PP(iiP(to, now), P(mincost[now][to][(int)new_speed], new_speed)));
        }
      }
    }
  }

  if (ans == INF)
    cout << "unreachable" << endl;
  else
    cout << setiosflags(ios::fixed) << setprecision(5) << ans << endl;
}

int main() {

  while (true) {
    cin >> n >> m;
    if (n + m == 0)
      break;
    G.clear();
    G.resize(n + 1);
    rep(i, n + 1) rep(j, n + 1) rep(k, 31) mincost[i][j][k] = INF;

    cin >> s >> g;
    rep(i, m) {
      int x, y;
      double d, c;
      cin >> x >> y >> d >> c;
      G[x].push_back(iP(y, P(d, c)));
      G[y].push_back(iP(x, P(d, c)));
    }

    dijkstra();
  }
  return 0;
}