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

#include <iostream>
#include <mutex>
#include <queue>
#include <string>
#include <vector>
using namespace std;

const double INF = 1e9;

int n, m, s, g;

// [n][prev][v];
double dp[32][32][32];

struct edge {
  int to, c;
  double length;

  edge(int to, int c, double l) : to(to), c(c), length(l) {}
};

vector<edge> G[32];

struct state {
  int n, prev, v;
  double time;

  state(int n, int prev, int v, double time)
      : n(n), prev(prev), v(v), time(time) {}
  bool operator>(const state &s) const { return time > s.time; }
};

void solve() {
  priority_queue<state, vector<state>, greater<state>> q;
  q.push(state(s, -1, 1, 0.0));
  while (!q.empty()) {
    state s = q.top();
    q.pop();
    if (s.prev != -1 && dp[s.n][s.prev][s.v] <= s.time)
      continue;

    if (s.n == g && s.v == 1) {
      cout << s.time << endl;
      return;
    }

    if (s.prev != -1)
      dp[s.n][s.prev][s.v] = s.time;

    int dv[] = {0, 1, -1};
    for (int i = 0; i < G[s.n].size(); i++) {
      for (int j = 0; j < ((s.prev == -1) ? 1 : 3); j++) {
        int nv = s.v + dv[j];
        if (nv > 0 && nv <= G[s.n][i].c && G[s.n][i].to != s.prev &&
            s.time + G[s.n][i].length / nv < dp[G[s.n][i].to][s.n][nv])
          q.push(state(G[s.n][i].to, s.n, nv, s.time + G[s.n][i].length / nv));
      }
    }
  }

  cout << "unreachable" << endl;
}

int main() {
  while (cin >> n >> m, n | m) {
    cin >> s >> g;

    for (int i = 0; i < 32; i++) {
      G[i].clear();
    }
    for (int i = 0; i < m; i++) {
      int x, y, c;
      double d;
      cin >> x >> y >> d >> c;
      G[x].push_back(edge(y, c, d));
      G[y].push_back(edge(x, c, d));
    }

    for (int i = 0; i < 31; i++) {
      for (int j = 0; j < 31; j++) {
        for (int k = 0; k < 31; k++) {
          dp[i][j][k] = INF;
        }
      }
    }

    solve();
  }
}

Error: WA

Fixed submission:

#include <iostream>
#include <mutex>
#include <queue>
#include <string>
#include <vector>
using namespace std;

const double INF = 1e9;

int n, m, s, g;

// [n][prev][v];
double dp[32][32][32];

struct edge {
  int to, c;
  double length;

  edge(int to, int c, double l) : to(to), c(c), length(l) {}
};

vector<edge> G[32];

struct state {
  int n, prev, v;
  double time;

  state(int n, int prev, int v, double time)
      : n(n), prev(prev), v(v), time(time) {}
  bool operator>(const state &s) const { return time > s.time; }
};

void solve() {
  priority_queue<state, vector<state>, greater<state>> q;
  q.push(state(s, -1, 1, 0.0));
  while (!q.empty()) {
    state s = q.top();
    q.pop();
    if (s.prev != -1 && dp[s.n][s.prev][s.v] < s.time)
      continue;

    if (s.n == g && s.v == 1) {
      cout << s.time << endl;
      return;
    }

    if (s.prev != -1)
      dp[s.n][s.prev][s.v] = s.time;
    int dv[] = {0, 1, -1};
    for (int i = 0; i < G[s.n].size(); i++) {
      for (int j = 0; j < ((s.prev == -1) ? 1 : 3); j++) {
        int nv = s.v + dv[j];
        if (nv > 0 && nv <= G[s.n][i].c && G[s.n][i].to != s.prev)
          q.push(state(G[s.n][i].to, s.n, nv, s.time + G[s.n][i].length / nv));
      }
    }
  }

  cout << "unreachable" << endl;
}

int main() {
  while (cin >> n >> m, n | m) {
    cin >> s >> g;

    for (int i = 0; i < 32; i++) {
      G[i].clear();
    }
    for (int i = 0; i < m; i++) {
      int x, y, c;
      double d;
      cin >> x >> y >> d >> c;
      G[x].push_back(edge(y, c, d));
      G[y].push_back(edge(x, c, d));
    }

    for (int i = 0; i < 31; i++) {
      for (int j = 0; j < 31; j++) {
        for (int k = 0; k < 31; k++) {
          dp[i][j][k] = INF;
        }
      }
    }

    solve();
  }
}