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

#include <bits/stdc++.h>

using namespace std;

#define int long long
#define all(v) (v).begin(), (v).end()
#define resz(v, ...) (v).clear(), (v).resize(__VA_ARGS__)
#define reps(i, m, n) for (int i = (int)(m); i < (int)(n); i++)
#define rep(i, n) reps(i, 0, n)

template <class T1, class T2> void chmin(T1 &a, T2 b) {
  if (a > b)
    a = b;
}
template <class T1, class T2> void chmax(T1 &a, T2 b) {
  if (a < b)
    a = b;
}

using Pi = pair<int, int>;
using Tapris = tuple<int, int, int>;
using vint = vector<int>;

const int inf = 1LL << 55;
const int mod = 1e9 + 7;

struct State {
  int l, r;
  double cost;
  State() {}
  State(int l, int r, double cost) : l(l), r(r), cost(cost) {}
  bool operator<(const State &rhs) const { return cost > rhs.cost; }
};

using Point = pair<double, double>;

inline double sq(double x) { return x * x; }

signed main() {
  cin.tie(0);
  ios_base::sync_with_stdio(0);
  cout << fixed << setprecision(12);

  int n;
  while (cin >> n, n) {
    vector<Point> ps;
    rep(i, n) {
      double x, y;
      cin >> x >> y;
      ps.emplace_back(x, y);
    }
    rep(i, n) {
      double x = ps[i].first, y = ps[i].second;
      rep(j, n - 1) {
        double x1 = ps[j].first, y1 = ps[j].second;
        double x2 = ps[j + 1].first, y2 = ps[j + 1].second;
        if (min(y1, y2) < y && y < max(y1, y2)) {
          double a = (y2 - y1) / (x2 - x1);
          ps.emplace_back((y - y1) / a + x1, y);
        }
      }
    }
    sort(all(ps));
    ps.erase(unique(all(ps)), ps.end());
    n = ps.size();
    // rep(i, n) cout << ps[i].first << " " << ps[i].second << endl;
    // vector<vector<double> > mincost(n, vector<double>(n, DBL_MAX/4));
    map<int, map<int, double>> mincost;
    auto dijkstra = [&]() {
      priority_queue<State> que;
      que.emplace(0, n - 1, 0);
      mincost[0][n - 1] = 0;
      while (!que.empty()) {
        State s = que.top();
        que.pop();
        // cout<<s.l<<" "<<s.r<<" "<<ps[s.l].second<<" "<<ps[s.r].second<<"
        // "<<s.cost<<endl;
        if (s.l == s.r)
          return s.cost;
        // rep(bit, 1<<2) {
        reps(i, -1, 2) reps(j, -1, 2) {
          int nl = s.l + i, nr = s.r + j;
          // if((bit>>0)&1) ++nl; else --nl;
          // if((bit>>1)&1) ++nr; else --nr;
          if (nl < 0 || n <= nl || nr < 0 || n <= nr)
            continue;
          double xl = ps[s.l].first, yl = ps[s.l].second;
          double nxl = ps[nl].first, nyl = ps[nl].second;
          double xr = ps[s.r].first, yr = ps[s.r].second;
          double nxr = ps[nr].first, nyr = ps[nr].second;
          // cout<<nl<<" "<<nr<<" "<<nyl<<" "<<nyr<<endl;
          if (nyl != nyr)
            continue;
          double ncost = s.cost + sqrt(sq(nxl - xl) + sq(nyl - yl)) +
                         sqrt(sq(nxr - xr) + sq(nyr - yr));
          if (!mincost[nl].count(nr) || ncost < mincost[nl][nr]) {
            que.emplace(nl, nr, ncost);
            mincost[nl][nr] = ncost;
          }
        }
      }
      return -1.0;
    };
    cout << dijkstra() << endl;
  }

  return 0;
}


Error: MLE

Fixed submission:

#include <bits/stdc++.h>

using namespace std;

#define int long long
#define all(v) (v).begin(), (v).end()
#define resz(v, ...) (v).clear(), (v).resize(__VA_ARGS__)
#define reps(i, m, n) for (int i = (int)(m); i < (int)(n); i++)
#define rep(i, n) reps(i, 0, n)

template <class T1, class T2> void chmin(T1 &a, T2 b) {
  if (a > b)
    a = b;
}
template <class T1, class T2> void chmax(T1 &a, T2 b) {
  if (a < b)
    a = b;
}

using Pi = pair<int, int>;
using Tapris = tuple<int, int, int>;
using vint = vector<int>;

const int inf = 1LL << 55;
const int mod = 1e9 + 7;

struct State {
  int l, r;
  double cost;
  State() {}
  State(int l, int r, double cost) : l(l), r(r), cost(cost) {}
  bool operator<(const State &rhs) const { return cost > rhs.cost; }
};

using Point = pair<double, double>;

inline double sq(double x) { return x * x; }

signed main() {
  cin.tie(0);
  ios_base::sync_with_stdio(0);
  cout << fixed << setprecision(12);

  int n;
  while (cin >> n, n) {
    vector<Point> ps;
    rep(i, n) {
      double x, y;
      cin >> x >> y;
      ps.emplace_back(x, y);
    }
    rep(i, n) {
      double x = ps[i].first, y = ps[i].second;
      rep(j, n - 1) {
        double x1 = ps[j].first, y1 = ps[j].second;
        double x2 = ps[j + 1].first, y2 = ps[j + 1].second;
        if (min(y1, y2) < y && y < max(y1, y2)) {
          double a = (y2 - y1) / (x2 - x1);
          ps.emplace_back((y - y1) / a + x1, y);
        }
      }
    }
    sort(all(ps));
    ps.erase(unique(all(ps)), ps.end());
    n = ps.size();
    // rep(i, n) cout << ps[i].first << " " << ps[i].second << endl;
    vector<vector<double>> mincost(n, vector<double>(n, DBL_MAX / 4));
    auto dijkstra = [&]() {
      priority_queue<State> que;
      que.emplace(0, n - 1, 0);
      mincost[0][n - 1] = 0;
      while (!que.empty()) {
        State s = que.top();
        que.pop();
        // cout<<s.l<<" "<<s.r<<" "<<ps[s.l].second<<" "<<ps[s.r].second<<"
        // "<<s.cost<<endl;
        if (s.l == s.r)
          return s.cost;
        // rep(bit, 1<<2) {
        reps(i, -1, 2) reps(j, -1, 2) {
          int nl = s.l + i, nr = s.r + j;
          // if((bit>>0)&1) ++nl; else --nl;
          // if((bit>>1)&1) ++nr; else --nr;
          if (nl < 0 || n <= nl || nr < 0 || n <= nr)
            continue;
          double xl = ps[s.l].first, yl = ps[s.l].second;
          double nxl = ps[nl].first, nyl = ps[nl].second;
          double xr = ps[s.r].first, yr = ps[s.r].second;
          double nxr = ps[nr].first, nyr = ps[nr].second;
          // cout<<nl<<" "<<nr<<" "<<nyl<<" "<<nyr<<endl;
          if (nyl != nyr)
            continue;
          double ncost = s.cost + sqrt(sq(nxl - xl) + sq(nyl - yl)) +
                         sqrt(sq(nxr - xr) + sq(nyr - yr));
          if (ncost < mincost[nl][nr]) {
            que.emplace(nl, nr, ncost);
            mincost[nl][nr] = ncost;
          }
        }
      }
      return -1.0;
    };
    cout << dijkstra() << endl;
  }

  return 0;
}