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

#include "algorithm"
#include "bitset"
#include "cassert"
#include "climits"
#include "cmath"
#include "cstdio"
#include "ctime"
#include "functional"
#include "iomanip"
#include "iostream"
#include "list"
#include "map"
#include "numeric"
#include "queue"
#include "random"
#include "set"
#include "stack"
#include "string"
#include "unordered_map"
#include "unordered_set"

using namespace std;

constexpr long long int MOD = 1000000007;
// constexpr int MOD = 1000000007;
// constexpr int MOD = 998244353;
// constexpr long long int MOD = 998244353;
constexpr long double EPS = 1e-12;

// int N, M, K, H, W, L, R;
long long int N, M, K, H, W, L, R;

int dp[60][30][60][30][2];

struct Node {
  int ly, lx, ry, rx, nx, cost;
  Node(const int lly, const int llx, const int rry, const int rrx,
       const int nnx, const int ccost) {
    ly = lly, lx = llx, ry = rry, rx = rrx, nx = nnx, cost = ccost;
  }
  void debug() {
    cout << ly << " " << lx << " " << ry << " " << rx << " " << nx << " "
         << cost << endl;
  }
  bool operator<(const Node &n) const { return cost > n.cost; }
};

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

  while (cin >> W >> H, H) {
    vector<vector<char>> field(H, vector<char>(W));
    for (auto &i : field)
      for (auto &j : i)
        cin >> j;
    reverse(field.begin(), field.end());
    int ans = MOD;
    for (int i = 0; i < H; i++) {
      for (int j = 0; j < W; j++) {
        for (int k = 0; k < H; k++) {
          for (int l = 0; l < W; l++) {
            for (int m = 0; m < 2; m++)
              dp[i][j][k][l][m] = MOD;
          }
        }
      }
    }
    priority_queue<Node> PQ;
    for (int k = 0; k < W; k++) {
      if (field[0][k] != 'S')
        continue;
      for (int j = -3; j < 0; j++) {
        for (int i = -3 - j; i <= j + 3; i++) {
          if (0 + i < 0 || 0 + i >= H || k + j < 0 || k + j >= W)
            continue;
          if (field[0 + i][k + j] == 'X')
            continue;
          int add = 0;
          if (field[0 + i][k + j] >= '0' && field[0 + i][k + j] <= '9') {
            add = field[0 + i][k + j] - '0';
          }
          if (dp[0 + i][k + j][0][k][1] > 0 + add) {
            dp[0 + i][k + j][0][k][1] = 0 + add;
            PQ.push(Node(0 + i, k + j, 0, k, 1, 0 + add));
          }
        }
        for (int j = 1; j <= 3; j++) {
          for (int i = j - 3; i <= 3 - j; i++) {
            if (0 + i < 0 || 0 + i >= H || k + j < 0 || k + j >= W)
              continue;
            if (field[0 + i][k + j] == 'X')
              continue;
            int add = 0;
            if (field[0 + i][k + j] >= '0' && field[0 + i][k + j] <= '9') {
              add = field[0 + i][k + j] - '0';
            }
            if (dp[0][k][0 + i][k + j][0] > 0 + add) {
              dp[0][k][0 + i][k + j][0] = 0 + add;
              PQ.push(Node(0, k, 0 + i, k + j, 0, 0 + add));
            }
          }
        }
      }
    }
    while (!PQ.empty()) {
      auto c = PQ.top();
      // c.debug();
      PQ.pop();
      if (c.nx == 0) {
        for (int j = -3; j < 0; j++) {
          for (int i = -3 - j; i <= j + 3; i++) {
            if (c.ry + i < 0 || c.ry + i >= H || c.rx + j < 0 || c.rx + j >= W)
              continue;
            if (field[c.ry + i][c.rx + j] == 'X')
              continue;
            int add = 0;
            if (field[c.ry + i][c.rx + j] >= '0' &&
                field[c.ry + i][c.rx + j] <= '9') {
              add = field[c.ry + i][c.rx + j] - '0';
            }
            if (dp[c.ry + i][c.rx + j][c.ry][c.rx][1] > c.cost + add) {
              dp[c.ry + i][c.rx + j][c.ry][c.rx][1] = c.cost + add;
              PQ.push(Node(c.ry + i, c.rx + j, c.ry, c.rx, 1, c.cost + add));
            }
          }
        }
      } else {
        for (int j = 1; j <= 3; j++) {
          for (int i = j - 3; i <= 3 - j; i++) {
            if (c.ly + i < 0 || c.ly + i >= H || c.lx + j < 0 || c.lx + j >= W)
              continue;
            if (field[c.ly + i][c.lx + j] == 'X')
              continue;
            int add = 0;
            if (field[c.ly + i][c.lx + j] >= '0' &&
                field[c.ly + i][c.lx + j] <= '9') {
              add = field[c.ly + i][c.lx + j] - '0';
            }
            if (dp[c.ly][c.lx][c.ly + i][c.lx + j][0] > c.cost + add) {
              dp[c.ly][c.lx][c.ly + i][c.lx + j][0] = c.cost + add;
              PQ.push(Node(c.ly, c.lx, c.ly + i, c.lx + j, 0, c.cost + add));
            }
          }
        }
      }
    }
    for (int i = 0; i < W; i++) {
      if (field[H - 1][i] == 'T') {
        for (int j = 0; j < H; j++) {
          for (int k = 0; k < W; k++) {
            for (int l = 0; l < 2; l++) {
              ans = min(ans, dp[H - 1][i][j][k][l]);
              ans = min(ans, dp[j][k][H - 1][i][l]);
            }
          }
        }
      }
    }
    if (ans == MOD)
      ans = -1;
    cout << ans << endl;
  }
  return 0;
}


Error: MLE

Fixed submission:

#include "algorithm"
#include "bitset"
#include "climits"
#include "cmath"
#include "cstdio"
#include "functional"
#include "iomanip"
#include "iostream"
#include "list"
#include "map"
#include "queue"
#include "random"
#include "set"
#include "stack"
#include "string"
#include "unordered_map"
#include "unordered_set"

using namespace std;

const long long int MOD = 1000000007;
const long double EPS = 1e-8;

long long int N, M, K, H, W, L, R;

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

  cin >> W >> H;
  vector<int> ans;
  while (H) {
    vector<vector<char>> field(H, vector<char>(W));
    for (int i = 0; i < H; i++) {
      for (int j = 0; j < W; j++) {
        cin >> field[i][j];
      }
    }
    int ret = MOD;
    vector<vector<vector<vector<vector<int>>>>> dp(
        H, vector<vector<vector<vector<int>>>>(
               W, vector<vector<vector<int>>>(
                      H, vector<vector<int>>(W, vector<int>(2, MOD)))));
    queue<pair<pair<pair<int, int>, pair<int, int>>, int>> Q;
    for (int i = 0; i < W; i++) {
      for (int j = i + 1; j < W; j++) {
        if (field[H - 1][i] == 'S' && field[H - 1][j] == 'S' && j - i <= 3) {
          dp[H - 1][i][H - 1][j][0] = 0;
          dp[H - 1][i][H - 1][j][1] = 0;
          Q.push({{{H - 1, i}, {H - 1, j}}, 0});
          Q.push({{{H - 1, i}, {H - 1, j}}, 1});
        }
      }
    }
    while (!Q.empty()) {
      int ly = Q.front().first.first.first;
      int lx = Q.front().first.first.second;
      int ry = Q.front().first.second.first;
      int rx = Q.front().first.second.second;
      int bf = Q.front().second;
      Q.pop();
      if (!bf) {
        for (int i = -2; i <= 2; i++) {
          for (int j = 1; j <= 3; j++) {
            if (abs(i) + j > 3)
              continue;
            int nry = ly + i;
            int nrx = lx + j;
            if (nry < 0 || nrx < 0 || nry >= H || nrx >= W)
              continue;
            if (field[nry][nrx] == 'X')
              continue;
            if (field[nry][nrx] == 'T') {
              ret = min(ret, dp[ly][lx][ry][rx][bf]);
              continue;
            }
            if (field[nry][nrx] == 'S') {
              if (dp[ly][lx][nry][nrx][!bf] > dp[ly][lx][ry][rx][bf]) {
                dp[ly][lx][nry][nrx][!bf] = dp[ly][lx][ry][rx][bf];
                Q.push({{{ly, lx}, {nry, nrx}}, !bf});
              }
              continue;
            }
            if (dp[ly][lx][nry][nrx][!bf] >
                dp[ly][lx][ry][rx][bf] + field[nry][nrx] - '0') {
              dp[ly][lx][nry][nrx][!bf] =
                  dp[ly][lx][ry][rx][bf] + field[nry][nrx] - '0';
              Q.push({{{ly, lx}, {nry, nrx}}, !bf});
            }
          }
        }
      } else {
        for (int i = -2; i <= 2; i++) {
          for (int j = -1; j >= -3; j--) {
            if (abs(i) - j > 3)
              continue;
            int nly = ry + i;
            int nlx = rx + j;
            if (nly < 0 || nlx < 0 || nly >= H || nlx >= W)
              continue;
            if (field[nly][nlx] == 'X')
              continue;
            if (field[nly][nlx] == 'T') {
              ret = min(ret, dp[ly][lx][ry][rx][bf]);
              continue;
            }
            if (field[nly][nlx] == 'S') {
              if (dp[nly][nlx][ry][rx][!bf] > dp[ly][lx][ry][rx][bf]) {
                dp[nly][nlx][ry][rx][!bf] = dp[ly][lx][ry][rx][bf];
                Q.push({{{nly, nlx}, {ry, rx}}, !bf});
              }
              continue;
            }
            if (dp[nly][nlx][ry][rx][!bf] >
                dp[ly][lx][ry][rx][bf] + field[nly][nlx] - '0') {
              dp[nly][nlx][ry][rx][!bf] =
                  dp[ly][lx][ry][rx][bf] + field[nly][nlx] - '0';
              Q.push({{{nly, nlx}, {ry, rx}}, !bf});
            }
          }
        }
      }
    }
    ans.push_back(ret);
    for (int i = 0; i < H; i++) {
      for (int j = 0; j < W; j++) {
        for (int k = 0; k < H; k++) {
          for (int l = 0; l < W; l++) {
            if (abs(i - k) + abs(j - l) > 3 || j >= l)
              continue;
            // cout << i << " " << j << " " << k << " " << l << endl;
            // cout << dp[i][j][k][l][0] << " " << dp[i][j][k][l][1] << endl;
          }
        }
      }
    }
    cin >> W >> H;
  }
  for (auto i : ans) {
    if (i == MOD)
      cout << -1 << endl;
    else
      cout << i << endl;
  }
  return 0;
}