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

#include <algorithm>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <vector>

using namespace std;

#define EPS (1e-10)
#define EQ(a, b) (abs((a) - (b)) < EPS)
#define EQV(a, b) (EQ((a).real(), (b).real()) && EQ((a).imag(), (b).imag()))

typedef long long ll;

const int MAX_SIZE = 10000;

struct edge {
  int to;
  int cost;
  int speedLimit;
};

class Situation {
public:
  double cost;
  int idx;
  int prvIdx;
  int speed;

  Situation(double cost_, int idx_, int prvIdx_, int speed_) {
    cost = cost_;
    idx = idx_;
    speed = speed_;
    prvIdx = prvIdx_;
  }
  Situation();
  bool operator<(const Situation &s) const { return s.cost < this->cost; }
};

// typedef pair<int,int> P;
int V;

const int MAX_V = 100;
const int MAX_SPEED = 50;

vector<edge> G[MAX_V];
double d[MAX_V][MAX_V][MAX_SPEED];
const int INF = 1000000000;

void dijkstra(int s) {
  priority_queue<Situation> que;
  for (int i = 0; i < MAX_V; i++)
    for (int k = 0; k < MAX_V; k++)
      for (int j = 0; j < MAX_SPEED; j++)
        d[i][k][j] = INF;
  d[0][s][1] = 0;
  que.push(Situation(0, s, 0, 1));
  while (!que.empty()) {
    Situation p = que.top();
    que.pop();
    int idx = p.idx;
    int pidx = p.prvIdx;
    double ccost = p.cost;
    int cspeed = p.speed;
    if (d[pidx][idx][cspeed] < p.cost)
      continue;
    for (int i = 0; i < G[idx].size(); i++) {
      edge e = G[idx][i];
      if (pidx == e.to)
        continue;
      for (int j = -1; j <= 1; j++) {
        if (pidx == 0)
          if (cspeed + j != 1)
            continue;
        if (cspeed + j >= 1 && e.speedLimit >= cspeed + j &&
            (d[idx][e.to][cspeed + j] >
                 d[pidx][idx][cspeed] + (double)e.cost / (cspeed + j) &&
             !EQ(d[idx][e.to][cspeed + j],
                 d[pidx][idx][cspeed] + (double)e.cost / (cspeed + j)))) {
          d[idx][e.to][cspeed + j] =
              d[pidx][idx][cspeed] + (double)e.cost / (cspeed + j);
          que.push(Situation(d[idx][e.to][cspeed + j], e.to, idx, cspeed + j));
        }
      }
    }
  }
}

int main() {

  int n, m, s, g;
  while (cin >> n >> m && !(n == 0 && m == 0)) {
    for (int i = 0; i < MAX_V; i++)
      G[i].clear();
    cin >> s >> g;
    for (int i = 0; i < m; i++) {
      int from, to, dist, lim;
      cin >> from >> to >> dist >> lim;
      edge e;
      e.cost = dist;
      e.to = to;
      e.speedLimit = lim;
      G[from].push_back(e);
      e.to = from;
      G[to].push_back(e);
    }
    dijkstra(s);
    double minTime = INF;
    for (int i = 0; i <= n; i++)
      minTime = min(minTime, d[i][g][1]);
    if (EQ(minTime, INF))
      cout << "unreachable" << endl;
    else
      printf("%.6f\\n", minTime);
  }

  return 0;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <complex>
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stdio.h>
#include <string>
#include <vector>

using namespace std;

#define EPS (1e-10)
#define EQ(a, b) (abs((a) - (b)) < EPS)
#define EQV(a, b) (EQ((a).real(), (b).real()) && EQ((a).imag(), (b).imag()))

typedef long long ll;

const int MAX_SIZE = 10000;

struct edge {
  int to;
  int cost;
  int speedLimit;
};

class Situation {
public:
  double cost;
  int idx;
  int prvIdx;
  int speed;

  Situation(double cost_, int idx_, int prvIdx_, int speed_) {
    cost = cost_;
    idx = idx_;
    speed = speed_;
    prvIdx = prvIdx_;
  }
  Situation();
  bool operator<(const Situation &s) const { return s.cost < this->cost; }
};

// typedef pair<int,int> P;
int V;

const int MAX_V = 100;
const int MAX_SPEED = 50;

vector<edge> G[MAX_V];
double d[MAX_V][MAX_V][MAX_SPEED];
const int INF = 1000000000;

void dijkstra(int s) {
  priority_queue<Situation> que;
  for (int i = 0; i < MAX_V; i++)
    for (int k = 0; k < MAX_V; k++)
      for (int j = 0; j < MAX_SPEED; j++)
        d[i][k][j] = INF;
  d[0][s][1] = 0;
  que.push(Situation(0, s, 0, 1));
  while (!que.empty()) {
    Situation p = que.top();
    que.pop();
    int idx = p.idx;
    int pidx = p.prvIdx;
    double ccost = p.cost;
    int cspeed = p.speed;
    // int v = p.idx;
    if (d[pidx][idx][cspeed] < p.cost)
      continue;
    for (int i = 0; i < G[idx].size(); i++) {
      edge e = G[idx][i];
      if (pidx == e.to)
        continue;
      for (int j = -1; j <= 1; j++) {
        if (pidx == 0) {
          if (cspeed + j != 1)
            continue;
        }
        if (cspeed + j >= 1 && e.speedLimit >= cspeed + j &&
            d[idx][e.to][cspeed + j] >
                d[pidx][idx][cspeed] + (double)e.cost / (cspeed + j)) {
          d[idx][e.to][cspeed + j] =
              d[pidx][idx][cspeed] + (double)e.cost / (cspeed + j);
          que.push(Situation(d[idx][e.to][cspeed + j], e.to, idx, cspeed + j));
        }
      }
    }
  }
}

int main() {

  int n, m, s, g;
  while (cin >> n >> m && !(n == 0 && m == 0)) {
    for (int i = 0; i < MAX_V; i++)
      G[i].clear();
    cin >> s >> g;
    for (int i = 0; i < m; i++) {
      int from, to, dist, lim;
      cin >> from >> to >> dist >> lim;
      edge e;
      e.cost = dist;
      e.to = to;
      e.speedLimit = lim;
      G[from].push_back(e);
      e.to = from;
      G[to].push_back(e);
    }
    dijkstra(s);
    double minTime = INF;
    for (int i = 0; i <= n; i++)
      minTime = min(minTime, d[i][g][1]);
    if (EQ(minTime, INF))
      cout << "unreachable" << endl;
    else
      printf("%.6f\\n", minTime);
  }

  return 0;
}