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

#include <algorithm>
#include <cassert>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <map>
#include <memory.h>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <vector>
using namespace std;

#define REP2(i, m, n) for (int i = (int)(m); i < (int)(n); i++)
#define REP(i, n) REP2(i, 0, n)
#define ALL(c) (c).begin(), (c).end()
#define ITER(c) __typeof((c).begin())
#define PB(e) push_back(e)
#define FOREACH(i, c) for (ITER(c) i = (c).begin(); i != (c).end(); ++i)
#define MP(a, b) make_pair(a, b)
#define PARITY(n) ((n)&1)

typedef long long ll;
typedef pair<int, int> PII;
typedef pair<int, PII> PIII;
typedef pair<double, PIII> PDIII;
const int INF = 1000 * 1000 * 1000 + 7;
const double EPS = 1e-10;

struct edge {
  int to, limit;
  double dis;
  edge() {}
  edge(int to, double dis, int limit) : to(to), limit(limit), dis(dis) {}
};

double dist[40][40][40];
vector<edge> G[40];

int main() {
  int n, m, s, g;
  while (cin >> n >> m, n + m) {
    REP(i, 40) G[i].clear();

    cin >> s >> g;
    s--, g--;
    REP(i, m) {
      int x, y, c;
      double dis;
      cin >> x >> y >> dis >> c;
      x--, y--;
      G[x].push_back(edge(y, dis, c));
      G[y].push_back(edge(x, dis, c));
    }

    double ans = -1;
    fill(&dist[0][0][0], &dist[0][0][0] + 40 * 40 * 40, 1e20);
    priority_queue<PDIII, vector<PDIII>, greater<PDIII>> que;
    dist[s][0][n] = 0.0;
    que.push(PDIII(0, PIII(s, PII(0, n))));

    while (!que.empty()) {
      double d = que.top().first;
      int pos = que.top().second.first;
      int v = que.top().second.second.first;
      int pre = que.top().second.second.second;
      que.pop();
      if (pos == g && v == 1) {
        ans = d;
        break;
      }
      if (d > dist[pos][v][pre])
        continue;

      REP(i, G[pos].size()) {
        int to = G[pos][i].to;
        for (int j = -1; j <= 1; j++) {
          if (to == pre)
            continue;
          int nv = v + j;

          if (nv < 1 || nv > G[pos][i].limit)
            continue;
          double tmp = G[pos][i].dis / nv + d;
          if (tmp < dist[to][nv][pos]) {
            dist[to][nv][pos] = tmp;
            que.push(PDIII(tmp, PIII(to, PII(nv, pos))));
          }
        }
      }
    }
    if (ans < 0) {
      cout << "unreachable" << endl;
    } else {
      printf("%.20lf\\n", ans);
    }
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cstdlib>
#include <ctime>
#include <iomanip>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;

typedef pair<int, int> P;
typedef pair<int, P> edge;
typedef pair<int, P> PP;
typedef pair<double, PP> PPP;

vector<edge> G[100];
double memo[40][40][40];
double need[200][40];
priority_queue<PPP, vector<PPP>, greater<PPP>> que;

int main() {
  int n, m;
  int s, g;
  for (int i = 0; i < 200; i++) {
    for (int j = 1; j < 40; j++)
      need[i][j] = (double)i / j;
  }
  while (cin >> n >> m && (n || m)) {
    scanf("%d%d", &s, &g);
    while (!que.empty())
      que.pop();
    fill(&memo[0][0][0], &memo[30][30][30] + 1, 1e10);
    for (int i = 0; i < m; i++) {
      int x1, y1, d, c;
      scanf("%d%d%d%d", &x1, &y1, &d, &c);
      G[x1].push_back(edge(y1, P(d, c)));
      G[y1].push_back(edge(x1, P(d, c)));
    }
    memo[s][0][32] = 0;

    que.push(PPP(memo[s][0][32], PP(0, P(s, 32))));
    bool ok = false;

    while (!que.empty()) {
      PPP ppp = que.top();
      que.pop();

      double dis = ppp.first;
      int v = ppp.second.first;
      int pos = ppp.second.second.first;
      int pre = ppp.second.second.second;

      if (dis > memo[pos][v][pre])
        continue;

      if (pos == g && v == 1) {
        cout << fixed << setprecision(9) << dis << endl;
        ok = true;
        break;
      }

      for (int i = -1; i <= 1; i++) {
        int v2 = v + i;
        for (int j = 0; j < (int)G[pos].size(); j++) {
          int to = G[pos][j].first;
          int li = G[pos][j].second.second;
          int d = G[pos][j].second.first;

          if (1 <= v2 && v2 <= li && to != pre) {
            if (memo[to][v2][pos] > dis + need[d][v2]) {
              memo[to][v2][pos] = dis + need[d][v2];
              que.push(PPP(memo[to][v2][pos], PP(v2, P(to, pos))));
            }
          }
        }
      }
    }
    if (!ok) {
      cout << "unreachable" << endl;
    }
    for (int i = 1; i <= 30; i++)
      G[i].clear();
  }
  return 0;
}