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

#include <cfloat>
#include <cmath>
#include <cstdio>
#include <iostream>
#include <queue>
#include <utility>
using namespace std;
#define EPS 1e-8

struct P {
  double t;
  char v, p, pre;
  P(double T = 0.0, int V = 0, int pp = 0, int PRE = 0) {
    t = T;
    v = V;
    p = pp;
    pre = PRE;
  };
  bool operator<(const P &p) const { return t > p.t; }
};
struct Path {
  char d, c;
  Path(int D = 0, int C = 0) {
    d = D;
    c = C;
  };
};

int main() {
  int n, m, s, g, x, y, d, c;
  Path path[30][30];
  priority_queue<P> q;

  while (cin >> n >> m && (n | m)) {
    cin >> s >> g;
    s--;
    g--;
    for (int i = 0; i < n; i++)
      for (int j = 0; j < n; j++) {
        path[i][j].d = -1.0;
        path[i][j].c = -1;
      }

    for (int i = 0; i < m; i++) {
      cin >> x >> y >> d >> c;
      x--;
      y--;
      path[x][y].d = d;
      path[x][y].c = c;
      path[y][x] = path[x][y];
    }

    double cost[30][35][30]; // place,velocity, pre
    int dv[3] = {1, 0, -1};
    for (int i = 0; i < n; i++)
      for (int j = 1; j < 31; j++)
        for (int k = 0; k < 31; k++)
          cost[i][j][k] = DBL_MAX;

    while (!q.empty())
      q.pop();
    for (int i = 0; i < n; i++) {
      if (path[s][i].c < 0)
        continue;
      q.push(P(path[s][i].d, 1, i, s)); // t ,v, np, pre
      cost[i][1][s] = path[s][i].d;
    }

    double ans = DBL_MAX;
    while (!q.empty()) {
      P p = q.top();
      q.pop();
      double t = p.t;
      int v = p.v, np = p.p, pre = p.pre;
      if (np == g && v == 1) {
        ans = t;
        break;
      }

      for (int i = 0; i < n; i++) {
        if (path[np][i].c < 0)
          continue; // たどり着けないノード
        if (i == pre)
          continue; // 前回のノード

        for (int j = 0; j < 3; j++) {
          int nv = v + dv[j];
          if (nv == 0 || nv > path[np][i].c)
            continue;
          double nCost = t + (double)path[np][i].d / nv;
          if (nCost > cost[g][1][np] || fabs(nCost - cost[g][1][np]) < EPS)
            continue;
          if (cost[i][nv][np] < nCost)
            continue;
          if (fabs(cost[i][nv][np] - nCost) < EPS)
            continue;
          cost[i][nv][np] = nCost;

          q.push(P(nCost, nv, i, np));
        }
      }
    }
    if (fabs(ans - DBL_MAX) < EPS)
      cout << "unreachable" << endl;
    else
      printf("%.6lf\\n", ans);
  }
  return 0;
}

Error: MLE

Fixed submission:

#include <cfloat>
#include <cmath>
#include <cstdio>
#include <iostream>
#include <queue>
#include <utility>
using namespace std;
#define EPS 1e-8
#define INF DBL_MAX

double cost[30][35]; // place,velocity

struct P {
  double t;
  char v, p, pre;
  P(double T = 0.0, int V = 0, int pp = 0, int PRE = 0) {
    t = T;
    v = V;
    p = pp;
    pre = PRE;
  };
  bool operator<(const P &p) const { return t > p.t; }
};
struct Path {
  char d, c;
  Path(int D = 0, int C = 0) {
    d = D;
    c = C;
  };
};

int main() {
  int n, m, s, g, x, y, d, c;
  Path path[30][30];
  priority_queue<P> q;

  while (cin >> n >> m && (n | m)) {
    cin >> s >> g;
    s--;
    g--;
    for (int i = 0; i < n; i++)
      for (int j = 0; j < n; j++) {
        path[i][j].d = -1.0;
        path[i][j].c = -1;
      }

    for (int i = 0; i < m; i++) {
      cin >> x >> y >> d >> c;
      x--;
      y--;
      path[x][y].d = d;
      path[x][y].c = c;
      path[y][x] = path[x][y];
    }

    int dv[3] = {1, 0, -1};
    for (int i = 0; i < n; i++)
      for (int j = 1; j < 31; j++)
        cost[i][j] = INF;

    while (!q.empty())
      q.pop();
    for (int i = 0; i < n; i++) {
      if (path[s][i].c < 0)
        continue;
      q.push(P(cost[i][1] = path[s][i].d, 1, i, -1));
    }

    while (!q.empty()) {
      P p = q.top();
      q.pop();
      double t = p.t;
      int v = p.v, np = p.p, pre = p.pre;
      if (np == g && v == 1)
        break;

      for (int i = 0; i < n; i++) {
        if (path[np][i].c < 0)
          continue; // たどり着けないノード
        if (i == pre)
          continue; // 前回のノード

        int j = 0;
        if (i == g)
          j = 2;
        for (; j < 3; j++) {
          int nv = v + dv[j];
          if (nv == 0 || nv > path[np][i].c)
            continue;
          double nCost = t + (double)path[np][i].d / nv;
          if (nCost > cost[g][1] || fabs(nCost - cost[g][1]) < EPS)
            continue;
          if (cost[i][nv] < nCost)
            continue;
          cost[i][nv] = nCost;

          q.push(P(nCost, nv, i, np));
        }
      }
    }
    if (fabs(cost[g][1] - INF) < EPS)
      cout << "unreachable" << endl;
    else
      printf("%.6lf\\n", cost[g][1]);
  }
  return 0;
}