Problem p00743 (C++)

Buggy submission (status: Runtime Error):
// #define DEBUG
#include <bits/stdc++.h>
using namespace std;
/*{{{*/ // template
#define REP(i, n) for (int i = 0; i < n; i++)
#define rep(i, n) for (int i = 0; i < n; i++)
#define INF 1 << 29
#define LINF LLONG_MAX / 3
#define MP make_pair
#define PB push_back
#define EB emplace_back
#define ALL(v) (v).begin(), (v).end()
#define all(v) ALL(v)
#define debug(x) cerr << #x << ":" << x << endl
#define debug2(x, y) cerr << #x << "," << #y ":" << x << "," << y << endl
#define CININIT cin.tie(0), ios::sync_with_stdio(false)
struct fin {
  fin() {
    cin.tie(0);
    ios::sync_with_stdio(false);
  }
} fin_;
struct Double {
  double d;
  explicit Double(double x) : d(x) {}
};
ostream &operator<<(ostream &os, const Double x) {
  os << fixed << setprecision(20) << x.d;
  return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
  os << "[";
  for (const auto &v : vec) {
    os << v << ",";
  }
  os << "]";
  return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
  os << "(" << p.first << "," << p.second << ")";
  return os;
}
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef vector<vi> vvi;
ll gcd(ll a, ll b) {
  if (b == 0)
    return a;
  else
    return gcd(b, a % b);
}

constexpr ll mod = 1e9 + 7;
const int dx[] = {1, 0, -1, 0}, dy[] = {0, 1, 0, -1};
/*}}}*/

// (time,speed,node,pre_node)
using P = pair<pair<double, int>, pair<int, int>>;

P makeP(double t, int s, int n, int np) {
  return make_pair(make_pair(t, s), make_pair(n, np));
}

void solve(int n, int m) {
  int start, goal;
  cin >> start >> goal;
  start--;
  goal--;
  vector<vector<int>> g(n, vector<int>(n, INF));
  vector<vector<int>> lim(n, vector<int>(n, 0));
  rep(i, m) {
    int x, y, d, c;
    cin >> x >> y >> d >> c;
    x--;
    y--;
    g[x][y] = d;
    g[y][x] = d;
    lim[x][y] = c;
    lim[y][x] = c;
  }

  double visited[32][32][32];
  rep(i, 32) rep(j, 32) rep(k, 32) visited[i][j][k] = DBL_MAX / 10;
  visited[start][0][start] = 0;

  priority_queue<P, vector<P>, greater<P>> que;
  que.push(makeP(0, 0, start, start));
  while (!que.empty()) {
    auto p = que.top();
    que.pop();
    double ti = p.first.first;
    int speed = p.first.second;
    int node = p.second.first;
    int pre = p.second.second;

#ifdef DEBUG
    cerr << "time : " << ti << " "
         << "node : " << node + 1 << " "
         << "speed " << speed << endl;
#endif
    if (node == goal and speed == 1) {
      cout << Double(ti) << endl;
      return;
    }

    if (ti > visited[node][speed][pre])
      continue;

    for (int next_node = 0; next_node < n; next_node++) {
      if (next_node == node or next_node == pre or g[node][next_node] == INF)
        continue;
      int d = g[node][next_node];
      int c = lim[node][next_node];
      for (int nspeed = speed - 1; nspeed <= speed + 1; nspeed++) {
        if (nspeed <= 0 or nspeed > c)
          continue;
        double nt = ti + (double)d / (double)nspeed;
        if (nt < visited[next_node][nspeed][pre]) {
#ifdef DEBUG
          cerr << "\ttime " << nt << " "
               << "node " << next_node + 1 << " speed " << nspeed << endl;
#endif
          visited[next_node][nspeed][node] = nt;
          que.push(makeP(nt, nspeed, next_node, node));
        }
      }
    }
  }
  cout << "unreachable" << endl;
}

int main() {
  int n, m;
  while (cin >> n >> m) {
    if (n == 0 && m == 0)
      break;
    solve(n, m);
  }
}

Fixed submission:
// #define DEBUG
#include <bits/stdc++.h>
using namespace std;
/*{{{*/ // template
#define REP(i, n) for (int i = 0; i < n; i++)
#define rep(i, n) for (int i = 0; i < n; i++)
#define INF 1 << 29
#define LINF LLONG_MAX / 3
#define MP make_pair
#define PB push_back
#define EB emplace_back
#define ALL(v) (v).begin(), (v).end()
#define all(v) ALL(v)
#define debug(x) cerr << #x << ":" << x << endl
#define debug2(x, y) cerr << #x << "," << #y ":" << x << "," << y << endl
#define CININIT cin.tie(0), ios::sync_with_stdio(false)
struct fin {
  fin() {
    cin.tie(0);
    ios::sync_with_stdio(false);
  }
} fin_;
struct Double {
  double d;
  explicit Double(double x) : d(x) {}
};
ostream &operator<<(ostream &os, const Double x) {
  os << fixed << setprecision(20) << x.d;
  return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
  os << "[";
  for (const auto &v : vec) {
    os << v << ",";
  }
  os << "]";
  return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
  os << "(" << p.first << "," << p.second << ")";
  return os;
}
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef vector<vi> vvi;
ll gcd(ll a, ll b) {
  if (b == 0)
    return a;
  else
    return gcd(b, a % b);
}

constexpr ll mod = 1e9 + 7;
const int dx[] = {1, 0, -1, 0}, dy[] = {0, 1, 0, -1};
/*}}}*/

// (time,speed,node,pre_node)
using P = pair<pair<double, int>, pair<int, int>>;

P makeP(double t, int s, int n, int np) {
  return make_pair(make_pair(t, s), make_pair(n, np));
}

void solve(int n, int m) {
  int start, goal;
  cin >> start >> goal;
  start--;
  goal--;
  vector<vector<int>> g(n, vector<int>(n, INF));
  vector<vector<int>> lim(n, vector<int>(n, 0));
  rep(i, m) {
    int x, y, d, c;
    cin >> x >> y >> d >> c;
    x--;
    y--;
    g[x][y] = d;
    g[y][x] = d;
    lim[x][y] = c;
    lim[y][x] = c;
  }

  double visited[32][32][32];
  rep(i, 32) rep(j, 32) rep(k, 32) visited[i][j][k] = DBL_MAX / 10;
  visited[start][0][start] = 0;

  priority_queue<P, vector<P>, greater<P>> que;
  que.push(makeP(0, 0, start, start));
  while (!que.empty()) {
    auto p = que.top();
    que.pop();
    double ti = p.first.first;
    int speed = p.first.second;
    int node = p.second.first;
    int pre = p.second.second;

#ifdef DEBUG
    cerr << "time : " << ti << " "
         << "node : " << node + 1 << " "
         << "speed " << speed << endl;
#endif
    if (node == goal and speed == 1) {
      cout << Double(ti) << endl;
      return;
    }

    if (ti > visited[node][speed][pre])
      continue;

    for (int next_node = 0; next_node < n; next_node++) {
      if (next_node == node or next_node == pre or g[node][next_node] == INF)
        continue;
      int d = g[node][next_node];
      int c = lim[node][next_node];
      for (int nspeed = speed - 1; nspeed <= speed + 1; nspeed++) {
        if (nspeed <= 0 or nspeed > c)
          continue;
        double nt = ti + (double)d / (double)nspeed;
        if (nt < visited[next_node][nspeed][node]) {
#ifdef DEBUG
          cerr << "\ttime " << nt << " "
               << "node " << next_node + 1 << " speed " << nspeed << endl;
#endif
          visited[next_node][nspeed][node] = nt;
          que.push(makeP(nt, nspeed, next_node, node));
        }
      }
    }
  }
  cout << "unreachable" << endl;
}

int main() {
  int n, m;
  while (cin >> n >> m) {
    if (n == 0 && m == 0)
      break;
    solve(n, m);
  }
}