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

#include <bits/stdc++.h>

using namespace std;

#define INF 1e9
typedef pair<int, int> pii;

struct Point {
  int x, y;
};

int cnt[5];
int dp[5][1002];
Point cr[5][1002];

int getMD(const Point &p1, const Point &p2) {
  return abs(p1.x - p2.x) + abs(p1.y - p2.y);
}

int main() {
  int H, W;
  while (cin >> W >> H, W) {
    char in;
    int sx, sy, gx, gy;
    memset(cnt, 0, sizeof(cnt));
    for (int i = 0; i < H; i++) {
      for (int j = 0; j < W; j++) {
        cin >> in;
        if (in == 'S') {
          sx = j;
          sy = i;
        } else if (in == 'G') {
          gx = j;
          gy = i;
        } else if (isdigit(in)) {
          int n = in - '1';
          cr[n][cnt[n]++] = (Point){j, i};
        }
      }
    }
    for (int i = 0; i < 5; i++) {
      cr[i][cnt[i]++] = (Point){sx, sy};
    }
    int res = INF, num = -1;
    for (int i = 0; i < 5; i++) {
      for (int j = 0; j < 5; j++) {
        for (int k = 0; k < cnt[j]; k++) {
          dp[j][k] = INF;
        }
      }
      dp[i][cnt[i] - 1] = 0;
      int nj = i, j = (i + 1) % 5, ej = (i > 0 ? i - 1 : 4);
      while (true) {
        int m = nj == i ? 0 : 1;
        for (int k = 0; k < cnt[nj] - m; k++) {
          if (dp[nj][k] == INF)
            continue;
          for (int l = 0; l < cnt[j] - m; l++) {
            dp[j][l] = min(dp[j][l], dp[nj][k] + getMD(cr[nj][k], cr[j][l]));
          }
        }
        if (j == ej) {
          for (int k = 0; k < cnt[j]; k++) {
            int d = dp[j][k] + getMD(cr[j][k], (Point){gx, gy});
            if (d < res) {
              res = d;
              num = i + 1;
            }
          }
          break;
        }
        nj++;
        nj %= 5;
        j++;
        j %= 5;
      }
    }
    if (res == INF) {
      cout << "NA" << endl;
    } else {
      cout << num << " " << res << endl;
    }
  }
  return 0;
}

Error: MLE

Fixed submission:

#include <bits/stdc++.h>

using namespace std;

#define MAX 1000
#define INF 1e9
typedef pair<int, int> pii;
typedef pair<pii, int> piii;

int H, W, sx, sy, gx, gy;
char field[MAX][MAX];
vector<pii> G;
int dist[MAX][MAX][1 << 5];
const int dx[4] = {-1, 0, 0, 1};
const int dy[4] = {0, -1, 1, 0};

struct State {
  int d, x, y, S;
  State(int d, int x, int y, int S) : d(d), x(x), y(y), S(S) {}
  bool operator<(const State &s) const { return d > s.d; }
};

int getDistance(int x1, int y1, int x2, int y2) {
  return abs(x1 - x2) + abs(y1 - y2);
}

bool check(int S, int p) {
  int pc = p - 1;
  if (pc < 0)
    pc = 4;
  return ((S >> pc) & 1);
}

int solve(int pc) {
  priority_queue<State> Q;
  Q.push(State(0, sx, sy, 1 << pc));
  dist[sy][sx][1 << pc] = 0;

  while (!Q.empty()) {
    State s = Q.top();
    Q.pop();
    int x = s.x, y = s.y, S = s.S;
    if (dist[y][x][S] < s.d)
      continue;
    if (gx == x && gy == y && S == (1 << 5) - 1) {
      return s.d;
    }
    for (int i = 0; i < (int)G.size(); i++) {
      int nx = G[i].first;
      int ny = G[i].second;
      int d = getDistance(x, y, nx, ny);
      if (d == 0)
        continue;
      if (field[ny][nx] == 'S' || field[ny][nx] == 'G') {
        if (dist[y][x][S] + d < dist[ny][nx][S]) {
          dist[ny][nx][S] = dist[y][x][S] + d;
          Q.push(State(dist[ny][nx][S], nx, ny, S));
        }
      } else {
        int npc = (int)(field[ny][nx] - '0') - 1;
        if (check(S, npc)) {
          int nS = S | (1 << npc);
          if (dist[y][x][S] + d < dist[ny][nx][nS]) {
            dist[ny][nx][nS] = dist[y][x][S] + d;
            Q.push(State(dist[ny][nx][nS], nx, ny, nS));
          }
        }
      }
    }
  }
  return INF;
}

int main() {
  while (cin >> W >> H, W) {
    G.clear();
    for (int i = 0; i < H; i++) {
      for (int j = 0; j < W; j++) {
        cin >> field[i][j];
        if (field[i][j] != '.') {
          G.push_back(pii(j, i));
        }
        if (field[i][j] == 'S') {
          sx = j, sy = i;
        } else if (field[i][j] == 'G') {
          gx = j, gy = i;
        }
      }
    }
    for (int i = 0; i < (int)G.size(); i++) {
      int x = G[i].first, y = G[i].second;
      for (int j = 0; j < (1 << 5); j++) {
        dist[y][x][j] = INF;
      }
    }
    int res = INF, num = -1;
    for (int i = 0; i < 5; i++) {
      int t = solve(i);
      if (t < res) {
        res = t;
        num = i + 1;
      }
    }
    if (res == INF) {
      cout << "NA" << endl;
    } else {
      cout << num << " " << res << endl;
    }
  }
  return 0;
}