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

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

typedef complex<double> P;
#define X real()
#define Y imag()

struct Node {
  int l, r;
  double d;
  Node(int l, int r, double d) : l(l), r(r), d(d){};
  bool operator<(const Node &n) const { return d > n.d; };
};

int N;
vector<P> M;

double solve() {
  vector<int> ys;
  for (auto p : M)
    ys.push_back(p.Y);
  sort(ys.begin(), ys.end());
  ys.erase(unique(ys.begin(), ys.end()), ys.end());

  vector<P> M2;

  for (int i = 0; i < N - 1; i++) {
    auto p1 = M[i], p2 = M[i + 1];
    vector<P> tm;
    bool rev = false;

    if (p2.Y != p1.Y) {
      if (p1.Y > p2.Y) {
        rev = true;
        swap(p1, p2);
      }
      for (auto y : ys) {
        if (p1.Y <= y && y <= p2.Y)
          tm.emplace_back((p2.X - p1.X) * (y - p1.Y) / (p2.Y - p1.Y) + p1.X, y);
      }
    } else {
      tm.emplace_back(p1);
      tm.emplace_back(p2);
    }
    if (rev)
      reverse(tm.begin(), tm.end());
    if (M2.size())
      M2.pop_back();
    M2.insert(M2.end(), tm.begin(), tm.end());
  }

  priority_queue<Node> que;
  // vector<vector<int>> done(M2.size(), vector<int>(M2.size()));
  // vector<vector<double>> d(M2.size(), vector<double>(M2.size(), 1e9));
  set<pair<int, int>> done;
  map<pair<int, int>, double> d;

  que.push(Node(0, M2.size() - 1, 0));
  // d[0][M2.size()-1] = 0;
  d[make_pair(0, M2.size() - 1)] = 0;

  while (!que.empty()) {
    auto v = que.top();
    que.pop();
    // if(done[v.l][v.r]++) continue;
    if (done.count(make_pair(v.l, v.r)))
      continue;
    done.insert(make_pair(v.l, v.r));

    if (v.r == v.l)
      return d[make_pair(v.l, v.r)]; // d[v.l][v.r];

    for (int nl = v.l - 1; nl <= v.l + 1; nl++) {
      for (int nr = v.r - 1; nr <= v.r + 1; nr++)
        if (0 <= nl && nl < M2.size() && 0 <= nr && nr < M2.size() &&
            M2[nl].Y == M2[nr].Y) {
          double cost = abs(M2[v.l] - M2[nl]) + abs(M2[v.r] - M2[nr]);
          if (d.count(make_pair(nl, nr)) == 0 ||
              d[make_pair(v.l, v.r)] + cost < d[make_pair(nl, nr)]) {
            d[make_pair(nl, nr)] = d[make_pair(v.l, v.r)] + cost;
            que.push(Node(nl, nr, d[make_pair(nl, nr)]));
          }
        }
    }
  }
  return -1;
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.precision(16);
  cout.setf(ios::fixed);
  while (cin >> N, N) {
    M.resize(N);
    for (int i = 0; i < N; i++) {
      int x, y;
      cin >> x >> y;
      M[i] = P(x, y);
    }
    cout << solve() << endl;
  }

  return 0;
}

Error: MLE

Fixed submission:

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

typedef complex<double> P;
#define X real()
#define Y imag()

struct Node {
  int l, r;
  double d;
  Node(int l, int r, double d) : l(l), r(r), d(d){};
  bool operator<(const Node &n) const { return d > n.d; };
};

int N;
vector<P> M;

double solve() {
  vector<int> ys;
  for (auto p : M)
    ys.push_back(p.Y);
  sort(ys.begin(), ys.end());
  ys.erase(unique(ys.begin(), ys.end()), ys.end());

  vector<P> M2;

  for (int i = 0; i < N - 1; i++) {
    auto p1 = M[i], p2 = M[i + 1];
    vector<P> tm;
    bool rev = false;

    if (p2.Y != p1.Y) {
      if (p1.Y > p2.Y) {
        rev = true;
        swap(p1, p2);
      }
      for (auto y : ys) {
        if (p1.Y <= y && y <= p2.Y)
          tm.emplace_back((p2.X - p1.X) * (y - p1.Y) / (p2.Y - p1.Y) + p1.X, y);
      }
    } else {
      tm.emplace_back(p1);
      tm.emplace_back(p2);
    }
    if (rev)
      reverse(tm.begin(), tm.end());
    if (M2.size())
      M2.pop_back();
    M2.insert(M2.end(), tm.begin(), tm.end());
  }

  priority_queue<Node> que;
  vector<vector<int>> done(M2.size(), vector<int>(M2.size()));
  vector<vector<double>> d(M2.size(), vector<double>(M2.size(), 1e9));

  que.push(Node(0, M2.size() - 1, 0));
  d[0][M2.size() - 1] = 0;

  while (!que.empty()) {
    auto v = que.top();
    que.pop();
    if (done[v.l][v.r]++)
      continue;

    if (v.r == v.l)
      return d[v.l][v.r];

    for (int nl = v.l - 1; nl <= v.l + 1; nl++) {
      for (int nr = v.r - 1; nr <= v.r + 1; nr++)
        if (0 <= nl && nl < M2.size() && 0 <= nr && nr < M2.size() &&
            M2[nl].Y == M2[nr].Y) {
          double cost = abs(M2[v.l] - M2[nl]) + abs(M2[v.r] - M2[nr]);
          if (d[v.l][v.r] + cost < d[nl][nr]) {
            d[nl][nr] = d[v.l][v.r] + cost;
            que.push(Node(nl, nr, d[nl][nr]));
          }
        }
    }
  }
  return -1;
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.precision(16);
  cout.setf(ios::fixed);
  while (cin >> N, N) {
    M.resize(N);
    for (int i = 0; i < N; i++) {
      int x, y;
      cin >> x >> y;
      M[i] = P(x, y);
    }
    cout << solve() << endl;
  }

  return 0;
}