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

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

#define REP(i, a, b) for (int i = int(a); i < int(b); i++)
#define dump(val) cerr << __LINE__ << ":\\t" << #val << " = " << (val) << endl

using namespace std;

typedef long long int lli;

template <typename T> vector<T> make_v(size_t a, T b) {
  return vector<T>(a, b);
}

template <typename... Ts> auto make_v(size_t a, Ts... ts) {
  return vector<decltype(make_v(ts...))>(a, make_v(ts...));
}

struct Edge {
  int x, y, foot, cost;
  Edge(int _x, int _y, int f, int c) : x(_x), y(_y), foot(f), cost(c) {}
  Edge() {}
  bool operator<(const Edge &e) const { return cost > e.cost; }
};

int main() {
  int w, h;
  while (cin >> w >> h, w + h) {
    auto mp = make_v(h, w, ' ');
    REP(i, 0, h) {
      REP(j, 0, w) { cin >> mp[i][j]; }
    }
    priority_queue<Edge, vector<Edge>> pq;
    REP(i, 0, h) {
      REP(j, 0, w) {
        if (mp[i][j] == 'S') {
          REP(x, -3, 4) {
            if (x == 0)
              continue;
            REP(y, -3, 4) {
              if (abs(x) + abs(y) > 3)
                continue;
              int nx = j + x;
              int ny = i + y;
              if (nx < 0 || ny < 0 || nx >= w || ny >= h || mp[ny][nx] == 'X')
                continue;
              pq.emplace(nx, ny, x < 0, mp[ny][nx] - '0');
            }
          }
        }
      }
    }
    const int inf = 1 << 29;
    auto Cost = make_v(w, h, 2, inf);
    auto used = make_v(w, h, 2, false);
    int ans = -1;
    while (pq.size()) {
      Edge e = pq.top();
      pq.pop();
      if (used[e.x][e.y][e.foot])
        continue;
      used[e.x][e.y][e.foot] = true;
      if (mp[e.y][e.x] == 'T') {
        ans = e.cost;
        break;
      }
      REP(x, 1, 4) {
        REP(y, -3, 4) {
          if (x + abs(y) > 3)
            continue;
          int nx = e.x + (2 * e.foot - 1) * x;
          int ny = e.y + y;
          if (nx < 0 || ny < 0 || nx >= w || ny >= h || mp[ny][nx] == 'X')
            continue;
          int nc = mp[ny][nx] - '0';
          if (mp[ny][nx] == 'T') {
            nc = 0;
          }
          if (Cost[nx][ny][!e.foot] > e.cost + nc) {
            Cost[nx][ny][!e.foot] = e.cost + nc;
            pq.emplace(nx, ny, !e.foot, Cost[nx][ny][!e.foot]);
          }
        }
      }
    }
    cout << ans << endl;
  }
  return 0;
}


Error: MLE

Fixed submission:

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

#define REP(i, a, b) for (int i = int(a); i < int(b); i++)
#define dump(val) cerr << __LINE__ << ":\\t" << #val << " = " << (val) << endl

using namespace std;

typedef long long int lli;

template <typename T> vector<T> make_v(size_t a, T b) {
  return vector<T>(a, b);
}

template <typename... Ts> auto make_v(size_t a, Ts... ts) {
  return vector<decltype(make_v(ts...))>(a, make_v(ts...));
}

struct Edge {
  int lx, ly, rx, ry, foot, cost;
  Edge(int _lx, int _ly, int _rx, int _ry, int f, int c)
      : lx(_lx), ly(_ly), rx(_rx), ry(_ry), foot(f), cost(c) {}
  Edge() {}
  bool operator<(const Edge &e) const { return cost > e.cost; }
};

int main() {
  int w, h;
  while (cin >> w >> h, w + h) {
    auto mp = make_v(h, w, ' ');
    REP(i, 0, h) {
      REP(j, 0, w) { cin >> mp[i][j]; }
    }
    priority_queue<Edge, vector<Edge>> pq;
    REP(i, 0, h) {
      REP(j, 0, w) {
        if (mp[i][j] == 'S') {
          REP(x, -3, 4) {
            REP(y, -3, 4) {
              if (abs(x) + abs(y) > 3)
                continue;
              int nx = j + x;
              int ny = i + y;
              if (nx < 0 || ny < 0 || nx >= w || ny >= h || mp[ny][nx] == 'X')
                continue;
              if (x < 0) {
                pq.emplace(nx, ny, j, i, 1, mp[ny][nx] - '0');
              } else if (x > 0) {
                pq.emplace(j, i, nx, ny, 0, mp[ny][nx] - '0');
              }
            }
          }
        }
      }
    }
    const int inf = 1 << 29;
    auto Cost = make_v(w, h, w, h, 2, inf);
    auto used = make_v(w, h, w, h, 2, false);
    int ans = -1;
    while (pq.size()) {
      Edge e = pq.top();
      pq.pop();
      if (used[e.lx][e.ly][e.rx][e.ry][e.foot])
        continue;
      used[e.lx][e.ly][e.rx][e.ry][e.foot] = true;
      //            cout << e.lx << ' ' << e.ly << ' ' << e.rx << ' ' << e.ry <<
      //            ' ' << e.foot << ' ' << e.cost << endl;
      if (mp[e.ly][e.lx] == 'T' || mp[e.ry][e.rx] == 'T') {
        ans = e.cost;
        break;
      }
      if (e.foot) {
        REP(x, 1, 4) {
          REP(y, -3, 4) {
            if (x + abs(y) > 3)
              continue;
            int nx = e.lx + x;
            int ny = e.ly + y;
            if (nx < 0 || ny < 0 || nx >= w || ny >= h || mp[ny][nx] == 'X')
              continue;
            int nc = mp[ny][nx] - '0';
            if (mp[ny][nx] == 'T') {
              nc = 0;
            }
            if (Cost[e.lx][e.ly][nx][ny][!e.foot] > e.cost + nc) {
              Cost[e.lx][e.ly][nx][ny][!e.foot] = e.cost + nc;
              pq.emplace(e.lx, e.ly, nx, ny, !e.foot,
                         Cost[e.lx][e.ly][nx][ny][!e.foot]);
            }
          }
        }
      } else {
        REP(x, 1, 4) {
          REP(y, -3, 4) {
            if (x + abs(y) > 3)
              continue;
            int nx = e.rx - x;
            int ny = e.ry + y;
            if (nx < 0 || ny < 0 || nx >= w || ny >= h || mp[ny][nx] == 'X')
              continue;
            int nc = mp[ny][nx] - '0';
            if (mp[ny][nx] == 'T') {
              nc = 0;
            }
            if (Cost[nx][ny][e.rx][e.ry][!e.foot] > e.cost + nc) {
              Cost[nx][ny][e.rx][e.ry][!e.foot] = e.cost + nc;
              pq.emplace(nx, ny, e.rx, e.ry, !e.foot,
                         Cost[nx][ny][e.rx][e.ry][!e.foot]);
            }
          }
        }
      }
    }
    cout << ans << endl;
  }
  return 0;
}