Problem p00215 (C++) — buggy submission, verdict: Runtime Error

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
#define INF (1 << 25)
int X, Y;
int sx, sy, gx, gy;

int x[5][1000];
int y[5][1000];
int memo[1000][5][5];
int sz[5];

int f(int w, int z, int s) {
  if ((z + 1) % 5 == s)
    return abs(x[z][w] - gx) + abs(y[z][w] - gy);
  if (~memo[w][z][s])
    return memo[w][z][s];
  int ans = INF;
  for (int i = 0; i < sz[(z + 1) % 5]; i++) {
    ans = min(ans, f(i, (z + 1) % 5, s) + abs(x[z][w] - x[(z + 1) % 5][i]) +
                       abs(y[z][w] - y[(z + 1) % 5][i]));
  }
  return memo[w][z][s] = ans;
}
int main() {
  while (cin >> X >> Y && X) {
    memset(memo, -1, sizeof(memo));
    for (int i = 0; i < 5; i++)
      sz[i] = 0;

    for (int i = 0; i < Y; i++)
      for (int j = 0; j < X; j++) {
        char c;
        scanf(" %c", &c);
        if (c == 'S') {
          sx = j, sy = i;
        } else if (c == 'G') {
          gx = j, gy = i;
        } else if (c != '.') {
          c = c - '1';
          x[c][sz[c]] = j;
          y[c][sz[c]++] = i;
        }
      }
    pair<int, int> ans(INF, -1);
    for (int i = 0; i < 5; i++) {
      for (int j = 0; j < sz[(i + 1) % 5]; j++) {
        ans = min(ans, make_pair(abs(sx - x[(i + 1) % 5][j]) +
                                     abs(sy - y[(i + 1) % 5][j]) +
                                     f(j, (i + 1) % 5, i),
                                 i));
      }
    }
    if (~ans.second)
      cout << ans.second + 1 << " " << ans.first << endl;
    else
      cout << "NA" << endl;
  }
}

Error: -11

Fixed submission:

#include <iostream>
#include <queue>
#include <vector>
using namespace std;
typedef pair<int, pair<int, int>> NODE;
#define pos second.second
#define e second.first
#define dist first
#define ppp(a, b, c) make_pair(a, make_pair(b, c))
int abs(int a) { return a < 0 ? -a : a; }

int main() {
  NODE q;
  int w, h, n, RET;
  char t;
  pair<int, int> s, g, ret;
  vector<pair<int, int>> tmp;
  vector<int> ele;
  int info[5000][5000];
  int memo[5000][1 << 5];
  int start[5000], goal[5000];

  while (cin >> w >> h && (w || h)) {
    ret.first = ret.second = (1 << 21);
    tmp.clear();
    ele.clear();
    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        cin >> t;
        if (t == 'S')
          s = make_pair(i, j);
        else if (t == 'G')
          g = make_pair(i, j);
        else if (t != '.') {
          tmp.push_back(make_pair(i, j));
          ele.push_back(1 << (t - '1'));
        }
      }
    }
    n = tmp.size();
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < n; j++) {
        if (ele[i] << 1 == ele[j] || (ele[i] == 16 && ele[j] == 1)) {
          info[i][j] = abs(tmp[i].first - tmp[j].first) +
                       abs(tmp[i].second - tmp[j].second);
        } else {
          info[i][j] = (1 << 21);
        }
      }
      start[i] = abs(tmp[i].first - s.first) + abs(tmp[i].second - s.second);
      goal[i] = abs(tmp[i].first - g.first) + abs(tmp[i].second - g.second);
    }
    for (int E = 0; E < 5; E++) {
      RET = (1 << 21);
      queue<NODE> Q;
      for (int i = 0; i < n; i++) {
        if ((1 << E) << 1 == ele[i] || ((1 << E) == 16 && ele[i] == 1))
          Q.push(ppp(start[i], (1 << E) + ele[i], i));
      }
      for (int i = 0; i < n; i++) {
        for (int j = 0; j < (1 << 5); j++) {
          memo[i][j] = (1 << 21);
        }
      }
      while (!Q.empty()) {
        q = Q.front();
        Q.pop();

        if (q.e == 31) {
          RET = min(RET, q.dist + goal[q.pos]);
        }
        for (int i = 0; i < n; i++) {
          if ((q.e & ele[i]) == 0) {
            if (q.dist + info[q.pos][i] < memo[i][q.e + ele[i]]) {
              Q.push(ppp(q.dist + info[q.pos][i], q.e + ele[i], i));
              memo[i][q.e + ele[i]] = q.dist + info[q.pos][i];
            }
          }
        }
      }
      if (RET < ret.first) {
        ret.first = RET;
        ret.second = E + 1;
      }
    }
    if (ret.second != (1 << 21))
      cout << ret.second << " " << ret.first << endl;
    else
      cout << "NA" << endl;
  }
}