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

#include <algorithm>
#include <iostream>
#include <queue>
#include <string>
#include <vector>

using namespace std;

#define rep(i, n) for (int i = 0; i < (n); ++i)
#define all(c) (c).begin(), (c).end()
#define exist(c, x) find(all(c), x) != (c).end()
#define mp(a, b) make_pair(a, b)
const int inf = 1 << 28;
const int dx[][9] = {{-2, -1, -1, 0, 0, 0, 1, 1, 2},
                     {-2, -1, -1, 0, 0, 0, 1, 1, 2}},
          dy[][9] = {{1, 1, 2, 1, 2, 3, 1, 2, 1},
                     {-1, -1, -2, -1, -2, -3, -1, -2, -1}};

int w, h;
vector<vector<int>> cost;

inline bool inrect(int x, int y) { return 0 <= x && x < h && 0 <= y && y < w; }

int solve() {
  vector<vector<vector<int>>> mem(h,
                                  vector<vector<int>>(w, vector<int>(2, inf)));
  auto comp = [&](const pair<int, int> &a, const pair<int, int> &b) {
    int ax = a.first / 100, ay = a.first % 100, bx = b.first / 100,
        by = b.first % 100;
    return mem[bx][by][b.second] < mem[ax][ay][a.second];
  };
  priority_queue<pair<int, int>, vector<pair<int, int>>, decltype(comp)> q(
      comp);
  vector<int> T;
  rep(j, w) {
    if (cost[0][j] == 0)
      T.push_back(j);
    if (cost[h - 1][j] == -1) {
      rep(foot, 2) {
        mem[h - 1][j][foot] = 0;
        q.push(mp((h - 1) * 100 + j, foot));
      }
    }
  }
  while (!q.empty()) {
    pair<int, int> p = q.top();
    q.pop();
    if (exist(T, p.first))
      continue;
    int x = p.first / 100, y = p.first % 100;
    rep(k, 9) {
      int nx = x + dx[p.second][k], ny = y + dy[p.second][k];
      if (inrect(nx, ny) && 0 <= cost[nx][ny] &&
          mem[nx][ny][p.second ^ 1] == inf) {
        mem[nx][ny][p.second ^ 1] = mem[x][y][p.second] + cost[nx][ny];
        q.push(mp(nx * 100 + ny, p.second ^ 1));
      }
    }
  }
  int res = inf;
  for (auto t : T)
    rep(k, 2) res = min(res, mem[0][t][k]);
  return res == inf ? -1 : res;
}

int main() {
  while (cin >> w >> h, w | h) {
    cin.ignore();
    cost.assign(h, vector<int>(w, 0));
    rep(i, h) {
      string in;
      getline(cin, in);
      in.erase(remove_if(all(in), [](char c) { return c == ' '; }), in.end());
      rep(j, w) cost[i][j] = in[j] == 'X'   ? -2
                             : in[j] == 'S' ? -1
                             : in[j] == 'T' ? 0
                                            : in[j] - '0';
    }
    cout << solve() << '\\n';
  }
  return 0;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <iostream>
#include <queue>
#include <string>
#include <vector>

using namespace std;

#define rep(i, n) for (int i = 0; i < (n); ++i)
#define all(c) (c).begin(), (c).end()
#define exist(c, x) find(all(c), x) != (c).end()
#define mp(a, b) make_pair(a, b)
const int inf = 1 << 28;
const int dx[][9] = {{-2, -1, -1, 0, 0, 0, 1, 1, 2},
                     {-2, -1, -1, 0, 0, 0, 1, 1, 2}},
          dy[][9] = {{1, 1, 2, 1, 2, 3, 1, 2, 1},
                     {-1, -1, -2, -1, -2, -3, -1, -2, -1}};

int w, h;
vector<vector<int>> cliff;
vector<vector<int>> gmem;

inline bool inrect(int x, int y) { return 0 <= x && x < h && 0 <= y && y < w; }

int calc(vector<int> T, int lf, int rf) {
  vector<vector<int>> &mem = gmem;
  auto comp = [&](const pair<int, int> &a, const pair<int, int> &b) {
    return mem[a.first][a.second] > mem[b.first][b.second];
  };
  priority_queue<pair<int, int>, vector<pair<int, int>>, decltype(comp)> q(
      comp);
  for (q.push(mp(lf, rf)); !q.empty();) {
    pair<int, int> p = q.top();
    q.pop();
    if (exist(T, p.first) || exist(T, p.second)) {
      return mem[p.first][p.second];
      continue;
    }
    int lx = p.first / 100, ly = p.first % 100, rx = p.second / 100,
        ry = p.second % 100;
    rep(i, 2) rep(j, 9) {
      int nx = (i ? rx : lx) + dx[i][j], ny = (i ? ry : ly) + dy[i][j];
      if (inrect(nx, ny) && 0 <= cliff[nx][ny]) {
        int cost = mem[p.first][p.second] + cliff[nx][ny], nxt = nx * 100 + ny;
        if (mem[i ? nxt : p.first][i ? p.second : nxt] <= cost)
          continue;
        mem[i ? nxt : p.first][i ? p.second : nxt] = cost;
        q.push(mp(i ? nxt : p.first, i ? p.second : nxt));
      }
    }
  }
  return inf;
}

int solve() {
  int res = inf;
  gmem.assign(h * 100 + w, vector<int>(h * 100 + w, inf));
  vector<int> T;
  rep(j, w) if (cliff[0][j] == 0) T.push_back(j);
  rep(k, w) if (cliff[h - 1][k] == -1) {
    int st = (h - 1) * 100 + k;
    rep(i, 2) rep(j, 9) {
      int nx = h - 1 + dx[i][j], ny = k + dy[i][j];
      if (inrect(nx, ny) && 0 <= cliff[nx][ny]) {
        int nxt = nx * 100 + ny;
        gmem[i ? nxt : st][i ? st : nxt] = cliff[nx][ny];
        res = min(res, calc(T, i ? nxt : st, i ? st : nxt));
      }
    }
  }
  return res == inf ? -1 : res;
}

int main() {
  while (cin >> w >> h, w | h) {
    cin.ignore();
    cliff.assign(h, vector<int>(w, 0));
    rep(i, h) {
      string in;
      getline(cin, in);
      in.erase(remove_if(all(in), [](char c) { return c == ' '; }), in.end());
      rep(j, w) cliff[i][j] = in[j] == 'X'   ? -2
                              : in[j] == 'S' ? -1
                              : in[j] == 'T' ? 0
                                             : in[j] - '0';
    }
    cout << solve() << '\\n';
  }
  return 0;
}