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

#include <algorithm>
#include <cstdio>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;

struct node {
  char pos;
  char prev;
  char speed;
  double dist;

  node(int pos_, int prev_, int speed_, double dist_)
      : pos(pos_), prev(prev_), speed(speed_), dist(dist_) {}

  bool operator<(const node &n) const {
    return dist > n.dist; // 逆
  }
};

struct road {
  char to;
  double dist;
  char c;

  road(int t, double d, int c_) : to(t), dist(d), c(c_) {}
};

int n, m;
int s, g;

vector<vector<road>> roads;
double mindist[31][31][31];

void solve() {
  fill(mindist[0][0], mindist[31][0], 9e9);

  priority_queue<node> pq;
  for (int i = 0; i < roads[s].size(); ++i) {
    road r = roads[s][i];
    pq.push(node(r.to, s, 1, r.dist));
    mindist[r.to][s][1] = r.dist;
  }

  while (!pq.empty()) {
    node nd = pq.top();
    pq.pop();

    if (mindist[nd.pos][nd.prev][nd.speed] != nd.dist) {
      continue;
    }

    if (nd.pos == g && nd.speed == 1) {
      printf("%f\\n", nd.dist);
      return;
    }

    for (int i = 0; i < roads[nd.pos].size(); ++i) {
      road r = roads[nd.pos][i];
      if (r.to == nd.prev) {
        continue;
      }

      for (int j = -1; j < 2; ++j) {
        if (nd.speed + j > 0 && nd.speed + j <= r.c) {
          double nextdist = nd.dist + r.dist / (nd.speed + j);
          if (mindist[r.to][nd.pos][nd.speed + j] > nextdist) {
            mindist[r.to][nd.pos][nd.speed + j] = nextdist;
            pq.push(node(r.to, nd.pos, nd.speed + j, nextdist));
          }
        }
      }
    }
  }

  puts("unreachable");
}

int main() {
  int x, y, d, c;
  while (cin >> n >> m, n != 0) {
    roads = vector<vector<road>>(n + 1);

    cin >> s >> g;

    for (int i = 0; i < m; ++i) {
      cin >> x >> y >> d >> c;
      roads[x].push_back(road(y, d, c));
      roads[y].push_back(road(x, d, c));
    }

    solve();
  }
}

Error: MLE

Fixed submission:

// MLE

#include <algorithm>
#include <cstdio>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;

struct node {
  char pos;
  char prev;
  char speed;
  double dist;

  node(int pos_, int prev_, int speed_, double dist_)
      : pos(pos_), prev(prev_), speed(speed_), dist(dist_) {}

  bool operator<(const node &n) const {
    return dist > n.dist; // 逆
  }
};

struct road {
  char to;
  double dist;
  char c;

  road(int t, double d, int c_) : to(t), dist(d), c(c_) {}
};

int n, m;
int s, g;

vector<vector<road>> roads;
double mindist[31][31][31];

void solve() {
  fill(mindist[0][0], mindist[31][0], 9e9);

  priority_queue<node> pq;
  for (int i = 0; i < roads[s].size(); ++i) {
    road r = roads[s][i];
    pq.push(node(r.to, s, 1, r.dist));
    mindist[r.to][s][1] = r.dist;
  }

  while (!pq.empty()) {
    node nd = pq.top();
    pq.pop();

    if (mindist[nd.pos][nd.prev][nd.speed] != nd.dist) {
      continue;
    }

    if (nd.pos == g && nd.speed == 1) {
      printf("%f\\n", nd.dist);
      return;
    }

    for (int i = 0; i < roads[nd.pos].size(); ++i) {
      road r = roads[nd.pos][i];
      if (r.to == nd.prev) {
        continue;
      }

      for (int j = -1; j < 2; ++j) {
        if (nd.speed + j > 0 && nd.speed + j <= r.c) {
          double nextdist = nd.dist + r.dist / (nd.speed + j);
          if (mindist[r.to][nd.pos][nd.speed + j] > nextdist) {
            mindist[r.to][nd.pos][nd.speed + j] = nextdist;
            pq.push(node(r.to, nd.pos, nd.speed + j, nextdist));
          }
        }
      }
    }
  }

  puts("unreachable");
}

int main() {
  int x, y, d, c;
  while (cin >> n >> m, n != 0) {
    roads = vector<vector<road>>(n + 1);

    cin >> s >> g;

    for (int i = 0; i < m; ++i) {
      cin >> x >> y >> d >> c;
      roads[x].push_back(road(y, d, c));
      roads[y].push_back(road(x, d, c));
    }

    solve();
  }
}