Problem p00743 (C++) — buggy submission, verdict: Runtime Error

#include <bits/stdc++.h>
using namespace std;

#define V vector

const double INF = 1e11;

struct state {
  int pos;
  double time;
  int vel;
  int prev;

  state() {}
  ~state() {}

  state(int a, double b, int c, int d) : pos(a), time(b), vel(c), prev(d) {}

  bool operator<(const state &o) const { return time > o.time; }
};

struct edge {
  int to;
  int time;
  int lim;

  edge() {}
  ~edge() {}

  edge(int a, int b, int c) : to(a), time(b), lim(c) {}
};

bool solve() {
  int n, m, s, g;
  cin >> n >> m;

  if (n == 0 && m == 0)
    return false;

  cin >> s >> g;
  --s;
  --g;

  V<V<edge>> graph(n, V<edge>(0));

  for (int j = 0; j < m; ++j) {
    int x, y, d, c;
    cin >> x >> y >> d >> c;
    --x;
    --y;
    graph[x].push_back(edge(y, d, c));
    graph[y].push_back(edge(x, d, c));
  }

  V<V<V<double>>> min_time(n, V<V<double>>(n, V<double>(31, INF)));
  priority_queue<state> que;

  que.push(state(s, 0.0, 0, s));
  min_time[s][s][0] = 0;

  while (!que.empty()) {
    state st = que.top();
    que.pop();

    if (st.time > min_time[st.pos][st.prev][st.vel]) {
      continue;
    }

    if (st.pos == g && st.vel == 1) {
      break;
    }

    for (edge &e : graph[st.pos]) {
      if (e.to == st.prev)
        continue;

      for (int a = -1; a <= 1; ++a) {
        int nv = st.vel + a;
        if (nv <= 0)
          continue;

        double t = st.time + (double)e.time / nv;

        if (nv <= e.lim && t < min_time[e.to][st.pos][nv]) {
          min_time[e.to][st.pos][nv] = t;
          que.push(state(e.to, t, nv, st.pos));
        }
      }
    }
  }

  double ret = INF;
  for (int j = 0; j < n; ++j) {
    ret = min(ret, min_time[g][j][1]);
  }

  if (ret == INF) {
    printf("unreachable\\n");
  } else {
    printf("%.12f\\n", ret);
  }

  return true;
}

int main() {
  while (solve())
    ;
  return 0;
}

Error: -11

Fixed submission:

#include <bits/stdc++.h>
using namespace std;

struct status {
  int pos;
  double dist;
  int vel;
  int prev;

  status() {}
  ~status() {}

  status(int a, double b, int c, int d) : pos(a), dist(b), vel(c), prev(d) {}

  bool operator<(const status &o) const { return dist < o.dist; }

  bool operator>(const status &o) const { return dist > o.dist; }
};

struct edge {
  int to;
  double dist;
  int lim;

  edge() {}
  ~edge() {}

  edge(int a, double b, int c) : to(a), dist(b), lim(c) {}
};

const int INF = 1 << 29;

bool solve() {
  int n, m, s, g;
  /*
   * n <- [1..20]
   * m <- [1..?]
   * s, g <- [1..n]
   * (x, y, d, c)
   *   x, y <- [1..n]
   *   d <- [1..100]
   *   c <- [1..30]
   */
  cin >> n >> m >> s >> g;

  if (n == 0 && m == 0 && s == 0 && g == 0)
    return false;

  --s;
  --g;

  vector<vector<edge>> graph(n, vector<edge>(0));

  for (int j = 0; j < m; ++j) {
    int x, y, d, c;
    cin >> x >> y >> d >> c;
    --x;
    --y;
    graph[x].push_back(edge(y, d, c));
    graph[y].push_back(edge(x, d, c));
  }

  vector<vector<double>> dist(n, vector<double>(30 + 1, INF));
  priority_queue<status, vector<status>, greater<status>> que;

  dist[s][0] = 0;
  que.push(status(s, 0.0, 0, -1));

  while (!que.empty()) {
    status st = que.top();
    que.pop();

    if (dist[st.pos][st.vel] < st.dist) {
      continue;
    }

    if (st.pos == g && st.vel == 1) {
      break;
    }

    for (edge &e : graph[st.pos]) {
      if (e.to == st.prev)
        continue;

      for (int a = -1; a <= 1; ++a) {
        int nv = st.vel + a;
        if (nv <= 0)
          continue;

        double d = st.dist + e.dist / nv;

        if (nv <= e.lim && d < dist[e.to][nv]) {
          dist[e.to][nv] = d;
          que.push(status(e.to, d, nv, st.pos));
        }
      }
    }
  }

  if (dist[g][1] == INF) {
    printf("unreachable\\n");
  } else {
    printf("%.10f\\n", dist[g][1]);
  }

  return true;
}

int main() {
  while (solve())
    ;
  return 0;
}