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

#include <bits/stdc++.h>
using namespace std;

using ld = double;
const ld INF = 1e15;
ld solve(int n) {
  vector<ld> x(n), y(n);
  for (int i = 0; i < n; i++)
    cin >> x[i] >> y[i];

  set<pair<ld, ld>> ps;
  for (int i = 0; i < n; i++) {
    ps.insert({x[i], y[i]});
    for (int j = 0; j + 1 < n; j++) {
      if (y[j] == y[j + 1])
        continue;
      if (min(y[j], y[j + 1]) <= y[i] && y[i] <= max(y[j], y[j + 1])) {
        ld px = (x[j + 1] - x[j]) * (y[i] - y[j]) / (y[j + 1] - y[j]) + x[j];
        ps.insert({px, y[i]});
      }
    }
  }

  vector<ld> tx, ty;
  for (auto &e : ps)
    tx.push_back(e.first), ty.push_back(e.second);
  ps.clear(), x.clear(), y.clear();
  int tn = tx.size();
  vector<map<int, ld>> d(tn);
  d[0][tn - 1] = 0;
  using Item = pair<ld, pair<int, int>>;
  priority_queue<Item, vector<Item>, greater<>> que;
  auto push = [&](int i, int j, ld v) {
    if (!d[i].count(j) || v < d[i][j]) {
      d[i][j] = v;
      que.push({v, {i, j}});
    }
  };
  auto isRange = [&](int i) { return 0 <= i && i < tn; };
  auto dist = [&](int f, int t) {
    return sqrt((tx[t] - tx[f]) * (tx[t] - tx[f]) +
                (ty[t] - ty[f]) * (ty[t] - ty[f]));
  };
  auto trans = [&](int i, int j) {
    for (int di = -1; di <= 1; di++) {
      for (int dj = -1; dj <= 1; dj++) {
        if (isRange(i + di) && isRange(j + dj)) {
          if (ty[i + di] == ty[j + dj])
            push(i + di, j + dj, d[i][j] + dist(i, i + di) + dist(j, j + dj));
        }
      }
    }
  };

  que.push({ld(0), {0, tn - 1}});
  while (!que.empty()) {
    auto ret = que.top();
    que.pop();
    int i = ret.second.first, j = ret.second.second;
    if (i == j)
      return ret.first;
    if (d[i][j] < ret.first)
      continue;
    trans(i, j);
  }
}
int main() {
  int n;
  while (cin >> n, n) {
    cout << fixed << setprecision(10);
    cout << solve(n) << endl;
  }
  return 0;
}


Error: MLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;

using ld = double;
const ld INF = 1e15;
ld solve(int n) {
  vector<ld> x(n), y(n);
  for (int i = 0; i < n; i++)
    cin >> x[i] >> y[i];

  set<pair<ld, ld>> ps;
  for (int i = 0; i < n; i++) {
    ps.insert({x[i], y[i]});
    for (int j = 0; j + 1 < n; j++) {
      if (y[j] == y[j + 1])
        continue;
      if (min(y[j], y[j + 1]) <= y[i] && y[i] <= max(y[j], y[j + 1])) {
        ld px = (x[j + 1] - x[j]) * (y[i] - y[j]) / (y[j + 1] - y[j]) + x[j];
        ps.insert({px, y[i]});
      }
    }
  }
  vector<ld> tx, ty;
  for (auto &e : ps)
    tx.push_back(e.first), ty.push_back(e.second);
  int tn = tx.size();
  vector<vector<ld>> d(tn, vector<ld>(tn, INF));
  d[0][tn - 1] = 0;
  using Item = pair<ld, pair<int, int>>;
  priority_queue<Item, vector<Item>, greater<>> que;
  auto push = [&](int i, int j, ld v) {
    if (v < d[i][j]) {
      d[i][j] = v;
      que.push({v, {i, j}});
    }
  };
  auto isRange = [&](int i) { return 0 <= i && i < tn; };
  auto dist = [&](int f, int t) {
    return sqrt((tx[t] - tx[f]) * (tx[t] - tx[f]) +
                (ty[t] - ty[f]) * (ty[t] - ty[f]));
  };
  auto trans = [&](int i, int j) {
    for (int di = -1; di <= 1; di++) {
      for (int dj = -1; dj <= 1; dj++) {
        if (isRange(i + di) && isRange(j + dj)) {
          if (ty[i + di] == ty[j + dj])
            push(i + di, j + dj, d[i][j] + dist(i, i + di) + dist(j, j + dj));
        }
      }
    }
  };

  que.push({ld(0), {0, tn - 1}});
  while (!que.empty()) {
    auto ret = que.top();
    que.pop();
    int i = ret.second.first, j = ret.second.second;
    if (d[i][j] < ret.first)
      continue;
    trans(i, j);
  }
  ld res = INF;
  for (int i = 0; i < tn; i++) {
    res = min(res, d[i][i]);
  }
  for (int i = 0; i + 1 < tn; i++) {
    res = min(res, d[i][i + 1] + dist(i, i + 1));
  }
  return res;
}
int main() {
  int n;
  while (cin >> n, n) {
    cout << fixed << setprecision(10);
    cout << solve(n) << endl;
  }
  return 0;
}