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

#include <algorithm>
#include <cstdio>
#include <queue>
#include <utility>
#include <vector>

using namespace std;

const int MAX_M = 100000, MAX_N = 100000, MAX_K = 200000;

struct P {
  int x, y;
  int index;
};

bool comp(const P &a, const P &b) {
  if (a.y != b.y) {
    return a.y < b.y;
  }
  return a.x < b.x;
}

bool comp2(const P &a, const P &b) {
  if (a.x != b.x) {
    return a.x < b.x;
  }
  return a.y < b.y;
}

int M, N, K;
P p[MAX_K + 2];

struct edge {
  int to, cost;
};

typedef pair<long long, int> PA;

const long long INF = 1000000000000000;

int V;
vector<edge> G[MAX_K * 2 + 4];

long long d[MAX_K * 2 + 4];

long long dijkstra() {
  priority_queue<PA, vector<PA>, greater<PA>> que;
  fill(d, d + V, INF);
  d[K + 2] = 0;
  que.push(PA(0, K + 2));
  while (!que.empty()) {
    PA pa = que.top();
    que.pop();
    int v = pa.second, dis = pa.first;
    if (dis > d[v])
      continue;
    for (int i = 0; i < G[v].size(); i++) {
      edge e = G[v][i];
      if (d[v] + e.cost < d[e.to]) {
        d[e.to] = d[v] + e.cost;
        que.push(PA(d[e.to], e.to));
      }
    }
  }
  return min(d[K + 1], d[2 * K + 3]);
}

int main() {
  scanf("%d %d %d", &M, &N, &K);
  for (int i = 0; i < K; i++) {
    int x, y;
    scanf("%d %d", &x, &y);
    p[i + 1].x = x;
    p[i + 1].y = y;
    p[i + 1].index = i + 1;
  }
  p[0].x = 1; // スタート
  p[0].y = 1;
  p[0].index = 0;
  p[K + 1].x = M; // ゴール
  p[K + 1].y = N;
  p[K + 1].index = K + 1;
  V = K * 2 + 4; // 頂点の個数
  // 辺を張る
  sort(p, p + K + 2, comp); // 横の辺を張る
  for (int i = 0; i < K + 1; i++) {
    if (p[i].y == p[i + 1].y) {
      int cost = p[i + 1].x - p[i].x;
      edge e{p[i + 1].index, cost};
      G[p[i].index].push_back(e);
      e.to = p[i].index;
      G[p[i + 1].index].push_back(e);
    }
  }
  sort(p, p + K + 2, comp2); // 縦の辺を張る
  for (int i = 0; i < K + 1; i++) {
    if (p[i].x == p[i + 1].x) {
      int cost = p[i + 1].y - p[i].y;
      edge e{p[i + 1].index + K + 2, cost};
      G[p[i].index + K + 2].push_back(e);
      e.to = p[i].index + K + 2;
      G[p[i + 1].index + K + 2].push_back(e);
    }
  }
  for (int i = 1; i <= K; i++) {
    edge e{i + K + 2, 1};
    G[i].push_back(e);
    e.to = i;
    G[i + K + 2].push_back(e);
  }
  long long res = dijkstra();
  if (res == INF) {
    res = -1;
  }
  printf("%lld\\n", res);
  return 0;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <queue>
#include <vector>

using namespace std;

const int MAX_M = 100000, MAX_N = 100000;
const int MAX_K = 200000;

int M, N, K;
int X[MAX_K + 1], Y[MAX_K + 1];

vector<int> map_x[MAX_M], map_y[MAX_N];

bool memo[MAX_K + 1][2];

struct D {
  long long cost;
  int k;
  int flg;
};

bool operator<(const D &a, const D &b) { return a.cost < b.cost; }

bool operator>(const D &a, const D &b) { return a.cost > b.cost; }

priority_queue<D, vector<D>, greater<D>> que;

void solve() {
  for (vector<int>::iterator i = map_x[0].begin(); i != map_x[0].end(); i++) {
    D data{Y[*i], *i, 1};
    que.push(data);
  }
  while (!que.empty()) {
    // 空になるまで続ける
    D d = que.top();
    que.pop();
    if (d.k == K - 1) {
      // ゴールについた
      printf("%lld\\n", d.cost);
      return;
    }
    if (memo[d.k][d.flg])
      continue;
    memo[d.k][d.flg] = true;
    int x = X[d.k], y = Y[d.k];
    if (d.flg == 0) {
      // 南北方向に開く
      for (vector<int>::iterator i = map_x[x].begin(); i != map_x[x].end();
           i++) {
        if (*i == d.k)
          continue;
        if (memo[*i][1])
          continue;
        D dd{d.cost + abs(Y[*i] - y) + 1, *i, 1};
        que.push(dd);
      }
    } else {
      // 東西方向に開く
      for (vector<int>::iterator i = map_y[y].begin(); i != map_y[y].end();
           i++) {
        if (*i == d.k)
          continue;
        if (memo[*i][0])
          continue;
        D dd{d.cost + abs(X[*i] - x) + 1, *i, 0};
        que.push(dd);
      }
    }
  }
  printf("-1\\n");
}

int main() {
  scanf("%d %d %d", &M, &N, &K);
  for (int i = 0; i < K; i++) {
    int x, y;
    scanf("%d %d", &x, &y);
    X[i] = x - 1;
    Y[i] = y - 1;
    map_x[x - 1].push_back(i);
    map_y[y - 1].push_back(i);
  }
  X[K] = M - 1;
  Y[K] = N - 1;
  map_x[M - 1].push_back(K);
  map_y[N - 1].push_back(K);
  K++;
  for (int i = 0; i < K; i++) {
    memo[i][0] = memo[i][1] = false;
  }
  solve();
  return 0;
}