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

#include <bits/stdc++.h>

using namespace std;

// typedef
//------------------------------------------
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef vector<string> VS;
typedef pair<double, int> PDI;
typedef long long LL;

// container util
//------------------------------------------
#define ALL(a) (a).begin(), (a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define PB push_back
#define MP make_pair
#define SZ(a) int((a).size())
#define EACH(i, c)                                                             \\
  for (typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)
#define EXIST(s, e) ((s).find(e) != (s).end())
#define SORT(c) sort((c).begin(), (c).end())

// repetition
//------------------------------------------
#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define REP(i, n) FOR(i, 0, n)

// constant
//--------------------------------------------
const double EPS = 1e-10;
const double PI = acos(-1.0);
const double INF = 1e9;
struct Edge {
  int to;
  double cost;

  Edge(int t, double c) : to(t), cost(c) {}
  bool operator>(const Edge &rhs) const { return cost > rhs.cost; }
};
typedef vector<vector<Edge>> Graph;

int N;

double dist(PDI p1, PDI p2) {
  return sqrt((p1.first - p2.first) * (p1.first - p2.first) +
              (p1.second - p2.second) * (p1.second - p2.second));
}

void Dijkstra(const Graph &edges, vector<double> &d, int s) {
  priority_queue<PDI, vector<PDI>, greater<PDI>> pq;
  fill(d.begin(), d.end(), INF);
  d[s] = 0;
  pq.push(MP(0, s));

  while (!pq.empty()) {
    PDI pii = pq.top();
    pq.pop();
    int v = pii.second;
    if (d[v] < pii.first)
      continue;
    for (unsigned int i = 0; i < edges[v].size(); ++i) {
      const Edge &e = edges[v][i];
      if (d[e.to] > d[v] + e.cost) {
        d[e.to] = d[v] + e.cost;
        pq.push(MP(d[e.to], e.to));
      }
    }
  }
}

int main() {
  cin.tie(0);
  ios_base::sync_with_stdio(false);

  while (cin >> N, N) {
    set<int> ys;
    vector<PDI> xy;
    REP(i, N) {
      int x, y;
      cin >> x >> y;
      xy.emplace_back(x, y);
      ys.insert(y);
    }
    for (int i = 0; i + 1 < SZ(xy); ++i) {
      if (xy[i].second < xy[i + 1].second) {
        auto it = ys.upper_bound(xy[i].second);
        if (it != ys.end() && *it < xy[i + 1].second) {
          xy.insert(xy.begin() + i + 1,
                    MP(xy[i].first + (*it - xy[i].second) *
                                         (xy[i + 1].first - xy[i].first) * 1. /
                                         (xy[i + 1].second - xy[i].second),
                       *it));
        }
      } else {
        auto it = ys.lower_bound(xy[i].second);
        if (it == ys.begin())
          continue;
        --it;
        if (*it > xy[i + 1].second) {
          xy.insert(xy.begin() + i + 1,
                    MP(xy[i].first + (*it - xy[i].second) *
                                         (xy[i + 1].first - xy[i].first) * 1. /
                                         (xy[i + 1].second - xy[i].second),
                       *it));
        }
      }
    }
    N = SZ(xy);
    /*
    Graph G(N*N, vector<Edge>());
    for(int i=0;i<N*N;++i){
      int a = i / N, b = i % N;
      for(int da=-1;da<=1;++da)
            for(int db=-1;db<=1;++db){
              if(da == 0 && db == 0) continue;
              int a_ = a + da, b_ = b + db;
              if(!(0 <= a_ && a_ < N && 0 <= b_ && b_ < N && a_ <= b_))
    continue; if(xy[a_].second != xy[b_].second) continue; int j = a_ * N + b_;
              G[i].emplace_back(j, dist(xy[a],xy[a_])+dist(xy[b],xy[b_]));
            }
    }
    */
    map<int, double> d;
    priority_queue<PDI, vector<PDI>, greater<PDI>> pq;
    d[N - 1] = 0;
    pq.push(MP(0, N - 1));

    while (!pq.empty()) {
      PDI pii = pq.top();
      pq.pop();
      int v = pii.second;
      if (d[v] < pii.first)
        continue;
      int a = v / N, b = v % N;
      for (int da = -1; da <= 1; ++da)
        for (int db = -1; db <= 1; ++db) {
          if (da == 0 && db == 0)
            continue;
          int a_ = a + da, b_ = b + db;
          if (!(0 <= a_ && a_ < N && 0 <= b_ && b_ < N && a_ <= b_))
            continue;
          if (xy[a_].second != xy[b_].second)
            continue;
          int j = a_ * N + b_;
          double cost = dist(xy[a], xy[a_]) + dist(xy[b], xy[b_]);
          if (!d.count(j) || d[j] > d[v] + cost) {
            d[j] = d[v] + cost;
            pq.push(MP(d[j], j));
          }
        }
    }

    double ans = INF;
    REP(i, N) ans = min(ans, d[i * N + i]);

    cout << fixed << setprecision(9) << ans << endl;
  }

  return 0;
}

Error: MLE

Fixed submission:

#include <bits/stdc++.h>

using namespace std;

// typedef
//------------------------------------------
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef vector<string> VS;
typedef pair<double, int> PDI;
typedef long long LL;

// container util
//------------------------------------------
#define ALL(a) (a).begin(), (a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define PB push_back
#define MP make_pair
#define SZ(a) int((a).size())
#define EACH(i, c)                                                             \\
  for (typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)
#define EXIST(s, e) ((s).find(e) != (s).end())
#define SORT(c) sort((c).begin(), (c).end())

// repetition
//------------------------------------------
#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define REP(i, n) FOR(i, 0, n)

// constant
//--------------------------------------------
const double EPS = 1e-10;
const double PI = acos(-1.0);
const double INF = 1e9;
struct Edge {
  int to;
  double cost;

  Edge(int t, double c) : to(t), cost(c) {}
  bool operator>(const Edge &rhs) const { return cost > rhs.cost; }
};
typedef vector<vector<Edge>> Graph;

int N;

double dist(PDI p1, PDI p2) {
  return sqrt((p1.first - p2.first) * (p1.first - p2.first) +
              (p1.second - p2.second) * (p1.second - p2.second));
}

void Dijkstra(const Graph &edges, vector<double> &d, int s) {
  priority_queue<PDI, vector<PDI>, greater<PDI>> pq;
  fill(d.begin(), d.end(), INF);
  d[s] = 0;
  pq.push(MP(0, s));

  while (!pq.empty()) {
    PDI pii = pq.top();
    pq.pop();
    int v = pii.second;
    if (d[v] < pii.first)
      continue;
    for (unsigned int i = 0; i < edges[v].size(); ++i) {
      const Edge &e = edges[v][i];
      if (d[e.to] > d[v] + e.cost) {
        d[e.to] = d[v] + e.cost;
        pq.push(MP(d[e.to], e.to));
      }
    }
  }
}

int main() {
  cin.tie(0);
  ios_base::sync_with_stdio(false);

  while (cin >> N, N) {
    set<int> ys;
    vector<PDI> xy;
    REP(i, N) {
      int x, y;
      cin >> x >> y;
      xy.emplace_back(x, y);
      ys.insert(y);
    }
    for (int i = 0; i + 1 < SZ(xy); ++i) {
      if (xy[i].second < xy[i + 1].second) {
        auto it = ys.upper_bound(xy[i].second);
        if (it != ys.end() && *it < xy[i + 1].second) {
          xy.insert(xy.begin() + i + 1,
                    MP(xy[i].first + (*it - xy[i].second) *
                                         (xy[i + 1].first - xy[i].first) * 1. /
                                         (xy[i + 1].second - xy[i].second),
                       *it));
        }
      } else {
        auto it = ys.lower_bound(xy[i].second);
        if (it == ys.begin())
          continue;
        --it;
        if (*it > xy[i + 1].second) {
          xy.insert(xy.begin() + i + 1,
                    MP(xy[i].first + (*it - xy[i].second) *
                                         (xy[i + 1].first - xy[i].first) * 1. /
                                         (xy[i + 1].second - xy[i].second),
                       *it));
        }
      }
    }
    N = SZ(xy);

    Graph G(N * N, vector<Edge>());
    for (int i = 0; i < N * N; ++i) {
      int a = i / N, b = i % N;
      for (int da = -1; da <= 1; ++da)
        for (int db = -1; db <= 1; ++db) {
          if (da == 0 && db == 0)
            continue;
          int a_ = a + da, b_ = b + db;
          if (!(0 <= a_ && a_ < N && 0 <= b_ && b_ < N && a_ <= b_))
            continue;
          if (xy[a_].second != xy[b_].second)
            continue;
          int j = a_ * N + b_;
          G[i].emplace_back(j, dist(xy[a], xy[a_]) + dist(xy[b], xy[b_]));
        }
    }

    vector<double> d(N * N);
    Dijkstra(G, d, N - 1);

    double ans = INF;
    REP(i, N) ans = min(ans, d[i * N + i]);

    cout << fixed << setprecision(9) << ans << endl;
  }

  return 0;
}