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

// テ・ツ淞コテヲツ慊ャテ」ツδ?」ツδウテ」ツδ療」ツδャテ」ツδシテ」ツδ?(テァツクツョテ・ツーツ湘ァツ可?

#include <bits/stdc++.h>
using namespace std;
#define rep(i, a, n) for (int(i) = (a); (i) < (n); (i)++)
#define repq(i, a, n) for (int(i) = (a); (i) <= (n); (i)++)
#define repr(i, a, n) for (int(i) = (a); (i) >= (n); (i)--)
#define int long long
template <typename T> void chmax(T &a, T b) { a = max(a, b); }
template <typename T> void chmin(T &a, T b) { a = min(a, b); }
template <typename T> void chadd(T &a, T b) { a = a + b; }
typedef pair<int, int> pii;
typedef long long ll;
constexpr ll INF = 1001001001001001LL;
constexpr ll MOD = 1000000007LL;
constexpr int T = 40;

int N, M, s, g;

// cur, prev, speed,
// prevsテ」ツ??、ツクツュティツコツォテ」ツ?ッテヲツ卍づゥツ鳴?
double dist[40][40][T][4];

struct Edge {
  int to;
  double cost;
  int lim;
};

struct Elem {
  int cur, prev, speed, prevs;
};

bool operator<(const Elem &a, const Elem &b) {
  return dist[a.cur][a.prev][a.speed][a.prevs] >
         dist[b.cur][b.prev][b.speed][b.prevs];
}

int dx[] = {-INF, -1, 0, 1};

signed main() {
  while (cin >> N >> M, N || M) {
    N++;
    cin >> s >> g;
    vector<vector<Edge>> G(N);
    rep(i, 0, M) {
      int x, y;
      double d;
      int c;
      cin >> x >> y >> d >> c;
      G[x].push_back(Edge{y, d, c});
      G[y].push_back(Edge{x, d, c});
    }

    rep(i, 0, N) rep(j, 0, N) rep(k, 0, T) rep(l, 0, 4) dist[i][j][k][l] = INF;
    dist[s][0][1][0] = 0.0;

    priority_queue<Elem> q;
    q.push(Elem{s, 0, 1, 0});

    double ans = INF;
    while (!q.empty()) {
      Elem t = q.top();
      q.pop();
      rep(i, 1, 4) {
        int sp = t.speed + dx[i];
        if (sp == 0)
          continue;
        for (auto x : G[t.cur]) {
          if (x.lim < t.speed || x.to == t.prev)
            continue;
          double c = x.cost / t.speed;
          // cur, prev, speed, prevs
          if (dist[x.to][t.cur][sp][i] >
              dist[t.cur][t.prev][t.speed][t.prevs] + c) {
            dist[x.to][t.cur][sp][i] =
                dist[t.cur][t.prev][t.speed][t.prevs] + c;
            if (x.to == g && t.speed == 1) {
              chmin(ans, dist[x.to][t.cur][sp][i]);
            }
            q.push(Elem{x.to, t.cur, sp, i});
          }
        }
      }
    }
    if (ans == INF)
      cout << "unreachable" << endl;
    else
      printf("%.12f\\n", ans);
  }
  return 0;
}

Error: MLE

Fixed submission:

// テ・ツ淞コテヲツ慊ャテ」ツδ?」ツδウテ」ツδ療」ツδャテ」ツδシテ」ツδ?(テァツクツョテ・ツーツ湘ァツ可?

#include <bits/stdc++.h>
using namespace std;
#define rep(i, a, n) for (int(i) = (a); (i) < (n); (i)++)
#define repq(i, a, n) for (int(i) = (a); (i) <= (n); (i)++)
#define repr(i, a, n) for (int(i) = (a); (i) >= (n); (i)--)
#define int long long
template <typename T> void chmax(T &a, T b) { a = max(a, b); }
template <typename T> void chmin(T &a, T b) { a = min(a, b); }
template <typename T> void chadd(T &a, T b) { a = a + b; }
typedef pair<int, int> pii;
typedef long long ll;
constexpr ll INF = 1001001001001001LL;
constexpr ll MOD = 1000000007LL;
constexpr int T = 40;

int N, M, s, g;

// cur, prev, speed,
// prevsテ」ツ??、ツクツュティツコツォテ」ツ?ッテヲツ卍づゥツ鳴?
double dist[40][40][T][4];

struct Edge {
  int to;
  double cost;
  int lim;
};

struct Elem {
  int cur, prev, speed, prevs;
};

bool operator<(const Elem &a, const Elem &b) {
  return dist[a.cur][a.speed][a.prevs] > dist[b.cur][b.speed][b.prevs];
}

int dx[] = {-INF, -1, 0, 1};

signed main() {
  while (cin >> N >> M, N || M) {
    N++;
    cin >> s >> g;
    vector<vector<Edge>> G(N);
    rep(i, 0, M) {
      int x, y;
      double d;
      int c;
      cin >> x >> y >> d >> c;
      G[x].push_back(Edge{y, d, c});
      G[y].push_back(Edge{x, d, c});
    }

    rep(i, 0, N) rep(j, 0, N) rep(k, 0, T) rep(l, 0, 4) dist[i][j][k][l] = INF;
    dist[s][0][1][0] = 0.0;

    priority_queue<Elem> q;
    q.push(Elem{s, 0, 1, 0});

    double ans = INF;
    while (!q.empty()) {
      Elem t = q.top();
      q.pop();
      rep(i, 1, 4) {
        int sp = t.speed + dx[i];
        if (sp == 0)
          continue;
        for (auto x : G[t.cur]) {
          if (x.lim < t.speed || x.to == t.prev)
            continue;
          double c = x.cost / t.speed;
          // printf("cost: %.12f\\n", c);
          // cur, prev, speed, prevs
          if (dist[x.to][t.cur][sp][i] >
              dist[t.cur][t.prev][t.speed][t.prevs] + c) {
            // printf("debug: dist[%lld][%lld][%lld][%lld] = %.12f\\n", x.to,
            // t.cur, sp, i, dist[x.to][t.cur][sp][i]);
            dist[x.to][t.cur][sp][i] =
                dist[t.cur][t.prev][t.speed][t.prevs] + c;
            if (x.to == g && t.speed == 1) {
              chmin(ans, dist[x.to][t.cur][sp][i]);
            }
            q.push(Elem{x.to, t.cur, sp, i});
          }
        }
      }
    }
    if (ans == INF)
      cout << "unreachable" << endl;
    else
      printf("%.12f\\n", ans);
  }
  return 0;
}