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

#include <algorithm>
#include <cstdio>
#include <queue>
#include <vector>
using namespace std;

const int inf = (int)30000;

int calc_cost(vector<vector<char>> &m, int x, int y) {
  int w = m.size(), h = m[0].size();
  if (x < 0 || x >= w || y < 0 || y >= h)
    return inf;
  if (m[x][y] < '0' || m[x][y] > '9')
    return (m[x][y] == 'T' || m[x][y] == 'S') ? 0 : inf;
  return m[x][y] - '0';
}

int calc_idx(vector<vector<char>> &m, int x1, int y1, int x2, int y2,
             int next) {
  int w = m.size(), h = m[0].size();
  return ((x1 * h + y1) * (w * h) + (x2 * h + y2)) * 2 + next;
}

int main() {
  while (true) {

    int w, h, wh;
    vector<vector<char>> m;
    const int dx[] = {1, 1, 1, 1, 1, 2, 2, 2, 3};
    const int dy[] = {-2, -1, 0, 1, 2, -1, 0, 1, 0};
    const int dir = 9;

    scanf("%d%d", &w, &h);
    if (w == 0)
      break;
    wh = w * h;
    m.resize(w);
    for (int i = 0; i < w; ++i)
      m[i].resize(h);
    for (int y = 0; y < h; ++y) {
      for (int x = 0; x < w; ++x)
        scanf(" %c", &m[x][y]);
    }

    vector<short> distl, distr;
    priority_queue<pair<int, int>> q;
    int ans = inf;

    distl.resize(wh * wh * 2, inf);
    distr.resize(wh * wh * 2, inf);

    for (int y = 0; y < h; ++y) {
      for (int x = 0; x < w; ++x) {

        if (m[x][y] != 'S')
          continue;

        for (int d = 0; d < dir; ++d) {
          int nx1 = x + dx[d], nx2 = x - dx[d];
          int ny1 = y + dy[d], ny2 = y + dy[d];
          int c1 = calc_cost(m, nx1, ny1);
          int c2 = calc_cost(m, nx2, ny2);
          if (c1 < inf)
            q.push(make_pair(-c1, calc_idx(m, x, y, nx1, ny1, 0)));
          if (c2 < inf)
            q.push(make_pair(-c2, calc_idx(m, nx2, ny2, x, y, 1)));
        }
      }
    }

    while (!q.empty()) {

      int cost = -q.top().first;
      int idx = q.top().second;
      q.pop();

      int x1 = ((idx / 2) / wh) / h;
      int y1 = ((idx / 2) / wh) % h;
      int x2 = ((idx / 2) % wh) / h;
      int y2 = ((idx / 2) % wh) % h;
      int next = idx % 2;

      // printf("%d %d %d %d (%d) -> %d  / %c %c\\n", x1, y1, x2, y2, next, cost,
      //	m[x1][y1], m[x2][y2]);

      if (next == 0) {
        if (distr[idx] <= cost)
          continue;
        distr[idx] = cost;
      } else {
        if (distl[idx] <= cost)
          continue;
        distl[idx] = cost;
      }

      if ((m[x1][y1] == 'T') || (m[x2][y2] == 'T')) {
        ans = min(ans, cost);
        continue;
      }

      if (next == 0) {

        for (int d = 0; d < dir; ++d) {
          int nx = x2 - dx[d], ny = y2 + dy[d];
          int c = calc_cost(m, nx, ny) + cost;
          int i = calc_idx(m, nx, ny, x2, y2, 1);
          if (c >= inf)
            continue;
          if (c >= distl[i])
            continue;
          q.push(make_pair(-c, i));
        }

      } else {

        for (int d = 0; d < dir; ++d) {
          int nx = x1 + dx[d], ny = y1 + dy[d];
          int c = calc_cost(m, nx, ny) + cost;
          int i = calc_idx(m, x1, y1, nx, ny, 0);
          if (c >= inf)
            continue;
          if (c >= distr[i])
            continue;
          q.push(make_pair(-c, i));
        }
      }
    }

    if (ans < inf)
      printf("%d\\n", ans);
    else
      printf("-1\\n");
  }

  return 0;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <cstdio>
#include <queue>
#include <vector>
using namespace std;

const int inf = (int)1.05e7;

int calc_cost(vector<vector<char>> &m, int x, int y) {
  int w = m.size(), h = m[0].size();
  if (x < 0 || x >= w || y < 0 || y >= h)
    return inf;
  if (m[x][y] < '0' || m[x][y] > '9')
    return (m[x][y] == 'T' || m[x][y] == 'S') ? 0 : inf;
  return m[x][y] - '0';
}

int calc_idx(vector<vector<char>> &m, int x1, int y1, int x2, int y2,
             int next) {
  int w = m.size(), h = m[0].size();
  return ((x1 * h + y1) * (w * h) + (x2 * h + y2)) * 2 + next;
}

int main() {
  while (true) {

    int w, h, wh;
    vector<vector<char>> m;
    const int dx[] = {1, 1, 1, 1, 1, 2, 2, 2, 3};
    const int dy[] = {-2, -1, 0, 1, 2, -1, 0, 1, 0};
    const int dir = 9;

    scanf("%d%d", &w, &h);
    if (w == 0)
      break;
    wh = w * h;
    m.resize(w);
    for (int i = 0; i < w; ++i)
      m[i].resize(h);
    for (int y = 0; y < h; ++y) {
      for (int x = 0; x < w; ++x)
        scanf(" %c", &m[x][y]);
    }

    vector<int> distl, distr;
    priority_queue<pair<int, int>> q;
    int ans = inf;

    distl.resize(wh * wh * 2, inf);
    distr.resize(wh * wh * 2, inf);

    for (int y = 0; y < h; ++y) {
      for (int x = 0; x < w; ++x) {

        if (m[x][y] != 'S')
          continue;

        for (int d = 0; d < dir; ++d) {
          int nx1 = x + dx[d], nx2 = x - dx[d];
          int ny1 = y + dy[d], ny2 = y + dy[d];
          int c1 = calc_cost(m, nx1, ny1);
          int c2 = calc_cost(m, nx2, ny2);
          if (c1 < inf)
            q.push(make_pair(-c1, calc_idx(m, x, y, nx1, ny1, 0)));
          if (c2 < inf)
            q.push(make_pair(-c2, calc_idx(m, nx2, ny2, x, y, 1)));
        }
      }
    }

    while (!q.empty()) {

      int cost = -q.top().first;
      int idx = q.top().second;
      q.pop();

      int x1 = ((idx / 2) / wh) / h;
      int y1 = ((idx / 2) / wh) % h;
      int x2 = ((idx / 2) % wh) / h;
      int y2 = ((idx / 2) % wh) % h;
      int next = idx % 2;

      // printf("%d %d %d %d (%d) -> %d  / %c %c\\n", x1, y1, x2, y2, next, cost,
      //	m[x1][y1], m[x2][y2]);

      if (next == 0) {
        if (distr[idx] <= cost)
          continue;
        distr[idx] = cost;
      } else {
        if (distl[idx] <= cost)
          continue;
        distl[idx] = cost;
      }

      if ((m[x1][y1] == 'T') || (m[x2][y2] == 'T')) {
        ans = min(ans, cost);
        continue;
      }

      if (next == 0) {

        for (int d = 0; d < dir; ++d) {
          int nx = x2 - dx[d], ny = y2 + dy[d];
          int c = calc_cost(m, nx, ny) + cost;
          int i = calc_idx(m, nx, ny, x2, y2, 1);
          if (c >= inf)
            continue;
          if (c >= distl[i])
            continue;
          q.push(make_pair(-c, i));
        }

      } else {

        for (int d = 0; d < dir; ++d) {
          int nx = x1 + dx[d], ny = y1 + dy[d];
          int c = calc_cost(m, nx, ny) + cost;
          int i = calc_idx(m, x1, y1, nx, ny, 0);
          if (c >= inf)
            continue;
          if (c >= distr[i])
            continue;
          q.push(make_pair(-c, i));
        }
      }
    }

    if (ans < inf)
      printf("%d\\n", ans);
    else
      printf("-1\\n");
  }

  return 0;
}