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

#include <cstdlib>
#include <iostream>
#include <vector>
using namespace std;
struct P {
  int x, y, cost;
};
#define INF (1 << 25)
#define rep(i, n) for (int i = 0; i < n; i++)

int dist(P a, P b) { return abs(a.x - b.x) + abs(a.y - b.y); }
int main() {
  int w, h;

  while (cin >> w >> h, w) {
    vector<P> data[5];
    P start, goal;

    start.cost = 0, goal.cost = 0;

    rep(i, h) rep(j, w) {
      char c;
      cin >> c;
      if (c != '.') {
        if (c == 'S') {
          start.x = j, start.y = i;
        } else if (c == 'G') {
          goal.x = j, goal.y = i;
        } else {
          P t = {j, i, 0};
          data[c - '1'].push_back(t);
        }
      }
    }
    int ret = INF, num;

    P dp[5][1000];
    rep(lp, 5) { // start
      rep(i, 5) rep(j, 1000) { dp[i][j].cost = INF; }

      int so = (lp + 1) % 5;
      rep(i, data[so].size()) {
        dp[so][i] = data[so][i];
        dp[so][i].cost = dist(data[so][i], start);
      }

      rep(Z, 3) { // kurikaesi
        int z = (lp + Z + 2) % 5;
        int prev = (z + 4) % 5;
        rep(i, data[prev].size()) { // izen
          rep(j, data[z].size()) {  // now
            int cost = dp[prev][i].cost + dist(dp[prev][i], data[z][j]);
            // cout << dist(dp[prev][i],data[z][j]) << endl;
            if (dp[z][j].cost > cost) {
              dp[z][j] = data[z][j];
              dp[z][j].cost = cost;
            }
          }
        }
      }
      rep(i, data[(lp + 4) % 5].size()) {
        int kCost = dp[(lp + 4) % 5][i].cost + dist(dp[(lp + 4) % 5][i], goal);
        if (kCost < ret) {
          ret = kCost, num = lp + 1;
        }
      }
    }

    if (ret == INF)
      cout << "NA" << endl;
    else
      cout << num << " " << ret << endl;
  }
}

Error: 0

Fixed submission:

#include <algorithm>
#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;
  vector<vector<int>> memo(1000, vector<int>(32, (1 << 21)));
  vector<int> goal(1000), start(1000);
  vector<vector<int>> info(1000, vector<int>(1000, (1 << 21)));

  while (cin >> w >> h && (w || h)) {
    pair<int, int> s, g, ret(make_pair(1 << 21, 1 << 21));
    vector<pair<int, int>> tmp;
    vector<int> ele;
    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);
      priority_queue<NODE, vector<NODE>, greater<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 < 32; j++) {
          memo[i][j] = (1 << 21);
        }
      }
      while (!Q.empty()) {
        q = Q.top();
        Q.pop();

        if (q.e == 31) {
          RET = min(RET, q.dist + goal[q.pos]);
          break;
        }
        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;
  }
}