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

#include <algorithm>
#include <cctype>
#include <cstring>
#include <functional>
#include <iostream>
#include <queue>
#include <tuple>
#include <vector>

#pragma warning(disable : 4996)

using namespace std;

const int dx[9] = {1, 1, 2, 1, 2, 3, 1, 2, 1};
const int dy[9] = {2, 1, 1, 0, 0, 0, -1, -1, -2};

int H, W, d[60][30][2];
char M[60][30];

int solve(int sx) {
  memset(d, -1, sizeof(d));

  priority_queue<tuple<int, int, int, int>, vector<tuple<int, int, int, int>>,
                 greater<tuple<int, int, int, int>>>
      que;

  que.push(make_tuple(0, sx, H - 1, 0));
  d[H - 1][sx][0] = 0;
  que.push(make_tuple(0, sx, H - 1, 1));
  d[H - 1][sx][1] = 0;

  while (!que.empty()) {
    int x = get<1>(que.top());
    int y = get<2>(que.top());
    int s = get<3>(que.top());

    que.pop();

    if (s == 0) {
      for (int dir = 0; dir < 9; dir++) {
        int x2 = x - dx[dir];
        int y2 = y + dy[dir];

        if (0 <= x2 && x2 < W && 0 <= y2 && y2 < H) {
          if (M[y2][x2] != 'X' && d[y2][x2][1] == -1) {
            d[y2][x2][1] =
                d[y][x][s] + (isdigit(M[y2][x2]) ? M[y2][x2] - 48 : 0);

            que.push(make_tuple(d[y2][x2][1], x2, y2, 1));
          }
        }
      }
    } else {
      for (int dir = 0; dir < 9; dir++) {
        int x2 = x + dx[dir];
        int y2 = y + dy[dir];

        if (0 <= x2 && x2 < W && 0 <= y2 && y2 < H) {
          if (M[y2][x2] != 'X' && d[y2][x2][0] == -1) {
            d[y2][x2][0] =
                d[y][x][s] + (isdigit(M[y2][x2]) ? M[y2][x2] - 48 : 0);

            que.push(make_tuple(d[y2][x2][0], x2, y2, 0));
          }
        }
      }
    }
  }

  int ret = 999999999;

  for (int i = 0; i < W; i++) {
    if (M[0][i] == 'T') {
      if (d[0][i][0] != -1)
        ret = min(ret, d[0][i][0]);
      if (d[0][i][1] != -1)
        ret = min(ret, d[0][i][1]);
    }
  }

  return ret;
}

int main() {
  while (true) {
    scanf("%d", &W);
    scanf("%d", &H);

    if (W == 0 && H == 0)
      break;

    for (int i = 0; i < H; i++) {
      for (int j = 0; j < W; j++) {
        cin >> M[i][j];
      }
    }

    int ret = 999999999;

    for (int i = 0; i < W; i++) {
      if (M[H - 1][i] == 'S') {
        ret = min(ret, solve(i));
      }
    }

    printf("%d\\n", ret == 999999999 ? -1 : ret);
  }

  return 0;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <cctype>
#include <cstring>
#include <functional>
#include <iostream>
#include <queue>
#include <tuple>
#include <vector>

#pragma warning(disable : 4996)

using namespace std;

const int dx[9] = {1, 1, 2, 1, 2, 3, 1, 2, 1};
const int dy[9] = {2, 1, 1, 0, 0, 0, -1, -1, -2};

int H, W, d[60][30][2];
char M[60][30];

int solve(int sx) {
  memset(d, -1, sizeof(d));

  priority_queue<tuple<int, int, int, int>, vector<tuple<int, int, int, int>>,
                 greater<tuple<int, int, int, int>>>
      que;

  que.push(make_tuple(0, 0, sx, H - 1));
  d[H - 1][sx][0] = 0;
  que.push(make_tuple(0, 0, sx, H - 1));
  d[H - 1][sx][1] = 0;

  while (!que.empty()) {
    int s = get<1>(que.top());
    int x = get<2>(que.top());
    int y = get<3>(que.top());

    que.pop();

    if (s == 0) {
      for (int dir = 0; dir < 9; dir++) {
        int x2 = x - dx[dir];
        int y2 = y + dy[dir];

        if (0 <= x2 && x2 < W && 0 <= y2 && y2 < H) {
          if (M[y2][x2] != 'X' && d[y2][x2][1] == -1) {
            d[y2][x2][1] =
                d[y][x][s] + (isdigit(M[y2][x2]) ? M[y2][x2] - 48 : 0);

            que.push(make_tuple(d[y2][x2][1], x2, y2, 1));
          }
        }
      }
    } else {
      for (int dir = 0; dir < 9; dir++) {
        int x2 = x + dx[dir];
        int y2 = y + dy[dir];

        if (0 <= x2 && x2 < W && 0 <= y2 && y2 < H) {
          if (M[y2][x2] != 'X' && d[y2][x2][0] == -1) {
            d[y2][x2][0] =
                d[y][x][s] + (isdigit(M[y2][x2]) ? M[y2][x2] - 48 : 0);

            que.push(make_tuple(d[y2][x2][0], x2, y2, 0));
          }
        }
      }
    }
  }

  int ret = 999999999;

  for (int i = 0; i < W; i++) {
    if (M[0][i] == 'T') {
      if (d[0][i][0] != -1)
        ret = min(ret, d[0][i][0]);
      if (d[0][i][1] != -1)
        ret = min(ret, d[0][i][1]);
    }
  }

  return ret;
}

int main() {
  while (true) {
    scanf("%d", &W);
    scanf("%d", &H);

    if (W == 0 && H == 0)
      break;

    for (int i = 0; i < H; i++) {
      for (int j = 0; j < W; j++) {
        cin >> M[i][j];
      }
    }

    int ret = 999999999;

    for (int i = 0; i < W; i++) {
      if (M[H - 1][i] == 'S') {
        ret = min(ret, solve(i));
      }
    }

    printf("%d\\n", ret);
  }

  return 0;
}