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

#include <cstdio>
#include <iostream>
#include <queue>

using namespace std;

const double INFTY = 1e10;

struct Edge {
  int src, dst, dist, limit;
  Edge() {}
  Edge(int s, int d, int di, int li) : src(s), dst(d), dist(di), limit(li) {}
};
typedef vector<vector<Edge>> Graph;

struct State {
  int src, dst, ver;
  double time;
  State() {}
  State(int s, int d, int v, double t) : src(s), dst(d), ver(v), time(t) {}
  bool operator<(const State &s) const { return time < s.time; }
  bool operator>(const State &s) const { return time > s.time; }
};

int main() {
  for (int n, m; cin >> n >> m, n | m;) {
    int start, goal;
    cin >> start >> goal;
    start--;
    goal--;
    Graph g(n);
    for (int i = 0; i < m; i++) {
      int s, d, di, li;
      cin >> s >> d >> di >> li;
      s--;
      d--;
      g[s].push_back(Edge(s, d, di, li));
      g[d].push_back(Edge(d, s, di, li));
    }

    double dist[30][30][31];
    for (int i = 0; i < 30; i++)
      for (int j = 0; j < 30; j++)
        for (int k = 0; k < 31; k++)
          dist[i][j][k] = INFTY;

    priority_queue<State, vector<State>, greater<State>> pq;
    pq.push(State(start, start, 0, 0));
    while (pq.size()) {
      State cur = pq.top();
      pq.pop();
      if (dist[cur.src][cur.dst][cur.ver] != INFTY)
        continue;
      dist[cur.src][cur.dst][cur.ver] = cur.time;
      for (int i = 0; i < g[cur.dst].size(); i++) {
        Edge e = g[cur.dst][i];
        if (e.dst == cur.src)
          continue;
        for (int j = -1; j <= 1; j++) {
          int nv = cur.ver + j;
          if (nv <= 0 || e.limit < nv || dist[e.src][e.dst][nv] != INFTY)
            continue;
          pq.push(State(e.src, e.dst, nv, cur.time + (double)e.dist / nv));
        }
      }
    }

    double res = INFTY;
    for (int i = 0; i < n; i++)
      res = min(res, dist[i][goal][1]);
    if (res == INFTY)
      puts("unreachable");
    else
      printf("%f\\n", res);
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <cstdio>
#include <iostream>
#include <queue>

using namespace std;

const double INFTY = 1e10;

struct Edge {
  int src, dst, dist, limit;
  Edge() {}
  Edge(int s, int d, int di, int li) : src(s), dst(d), dist(di), limit(li) {}
};
typedef vector<vector<Edge>> Graph;

struct State {
  int src, dst, ver;
  double time;
  State() {}
  State(int s, int d, int v, double t) : src(s), dst(d), ver(v), time(t) {}
  bool operator<(const State &s) const { return time < s.time; }
  bool operator>(const State &s) const { return time > s.time; }
};

int main() {
  for (int n, m; cin >> n >> m, n | m;) {
    int start, goal;
    cin >> start >> goal;
    start--;
    goal--;
    Graph g(n);
    for (int i = 0; i < m; i++) {
      int s, d, di, li;
      cin >> s >> d >> di >> li;
      s--;
      d--;
      g[s].push_back(Edge(s, d, di, li));
      g[d].push_back(Edge(d, s, di, li));
    }

    double dist[30][30][31];
    for (int i = 0; i < 30; i++)
      for (int j = 0; j < 30; j++)
        for (int k = 0; k < 31; k++)
          dist[i][j][k] = INFTY;
    priority_queue<State, vector<State>, greater<State>> pq;
    pq.push(State(start, start, 0, 0));
    while (pq.size()) {
      State cur = pq.top();
      pq.pop();
      if (dist[cur.src][cur.dst][cur.ver] != INFTY)
        continue;
      dist[cur.src][cur.dst][cur.ver] = cur.time;
      for (int i = 0; i < g[cur.dst].size(); i++) {
        Edge e = g[cur.dst][i];
        if (e.dst == cur.src)
          continue;
        for (int j = -1; j <= 1; j++) {
          int nv = cur.ver + j;
          if (nv <= 0 || e.limit < nv)
            continue;
          pq.push(State(e.src, e.dst, nv, cur.time + (double)e.dist / nv));
        }
      }
    }

    double res = INFTY;
    for (int i = 0; i < n; i++)
      res = min(res, dist[i][goal][1]);
    if (res == INFTY)
      puts("unreachable");
    else
      printf("%f\\n", res);
  }
  return 0;
}