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

#include <algorithm>
#include <cctype>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <fstream>
#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>
using namespace std;
inline int toInt(string s) {
  int v;
  istringstream sin(s);
  sin >> v;
  return v;
}
template <class T> inline string toStr(T x) {
  ostringstream sout;
  sout << x;
  return sout.str();
}
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<string> vs;
typedef pair<int, int> pii;
typedef long long ll;
#define ALL(a) (a).begin(), (a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define FOR(i, a, b) for (int i = (a); i <= (b); ++i)
#define REP(i, n) FOR(i, 0, (n)-1)
const double EPS = 1e-12;
const double PI = acos(-1.0);
const int INF = INT_MAX / 10;

typedef vector<double> vd;
typedef vector<vd> vvd;

struct state {
  int p, n, s;
  double c;
  state(int p, int n, int s, double c) : p(p), n(n), s(s), c(c){};
  bool operator<(const state &o) const { return o.c < c; }
};

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

    vvi d(n, vi(n, INF));
    vvi c(n, vi(n, INF));

    int x, y, dd, cc;
    REP(_, m) {
      cin >> x >> y >> dd >> cc;
      d[x - 1][y - 1] = d[y - 1][x - 1] = dd;
      c[x - 1][y - 1] = c[y - 1][x - 1] = cc;
    }

    priority_queue<state> Q;
    Q.push(state(-1, s - 1, 1, 0.0));
    vector<vvd> cost(n, vvd(n, vd(30 + 1, INF)));
    while (!Q.empty()) {
      state st = Q.top();
      Q.pop();
      if (st.n == g - 1 && st.s == 0) {
        cost[st.p][g - 1][0] = min(st.c, cost[st.p][g - 1][0]);
        continue;
      }
      if (st.s == 0) {
        continue;
      }
      REP(t, n) {
        if (st.p == t || st.n == t || d[st.n][t] == INF || c[st.n][t] < st.s) {
          continue;
        }

        double nc = st.c + (double)d[st.n][t] / st.s;
        FOR(p, -1, 1) {
          if (30 < st.s + p) {
            break;
          }
          if (nc < cost[st.n][t][st.s + p]) {
            cost[st.n][t][st.s + p] = nc;
            Q.push(state(st.n, t, st.s + p, nc));
          }
        }
      }
    }

    double ans = INF;
    REP(i, n) { ans = min(ans, cost[i][g - 1][0]); }

    if (ans == INF) {
      cout << "unreachable" << endl;
    } else {
      printf("%.5f\\n", ans);
    }
  }

  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cctype>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>
using namespace std;
inline int toInt(string s) {
  int v;
  istringstream sin(s);
  sin >> v;
  return v;
}
template <class T> inline string toStr(T x) {
  ostringstream sout;
  sout << x;
  return sout.str();
}
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<string> vs;
typedef pair<int, int> pii;
typedef long long ll;
#define ALL(a) (a).begin(), (a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define FOR(i, a, b) for (int i = (a); i <= (b); ++i)
#define REP(i, n) FOR(i, 0, (n)-1)
const double EPS = 1e-12;
const double PI = acos(-1.0);
const int INF = INT_MAX / 10;

typedef vector<double> vd;

struct state {
  int p, s;
  double c;
  state(int p, int s, double c) : p(p), s(s), c(c){};
  bool operator<(const state &o) const { return c < o.c; }
};

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

    vector<vd> road(n, vd(n, INF));
    vector<vd> limit(n, vd(n, INF));
    int x, y, d, c;
    REP(i, m) {
      cin >> x >> y >> d >> c;
      road[x - 1][y - 1] = road[y - 1][x - 1] = d;
      limit[x - 1][y - 1] = limit[y - 1][x - 1] = c;
    }

    vector<vd> cost(n, vd(30 + 1, INF));
    cost[s - 1][1] = 0;
    priority_queue<state> Q;
    Q.push(state(s - 1, 1, 0));
    while (!Q.empty()) {
      state st = Q.top();
      Q.pop();

      if (st.p == g - 1 && st.s == 0) {
        cost[g - 1][0] = min(cost[g - 1][0], st.c);
        continue;
      }

      if (st.s <= 0) {
        continue;
      }

      REP(i, n) {
        if (st.p != i && road[st.p][i] != INF && st.s <= limit[st.p][i]) {
          double nc = st.c + road[st.p][i] / (double)st.s;
          FOR(j, -1, 1) {
            int ns = st.s + j;
            if (ns <= 30 && nc < cost[i][ns]) {
              cost[i][ns] = nc;
              Q.push(state(i, ns, nc));
            }
          }
        }
      }
    }

    if (cost[g - 1][0] == INF) {
      cout << "unreachable" << endl;
    } else {
      printf("%.6f\\n", cost[g - 1][0]);
    }
  }

  return 0;
}