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

#include <algorithm>
#include <cstdio>
#include <iostream>
#include <queue>
#include <tr1/unordered_map>
#include <vector>
using namespace std;

int X, Y;
struct NODE {
  int x, y, z, cost, fc;
  NODE(int x, int y, int z, int cost, int fc)
      : x(x), y(y), z(z), cost(cost), fc(fc) {}
};
bool operator<(const NODE &a, const NODE &b) {
  return a.cost != b.cost ? a.cost > b.cost : a.fc > b.fc;
}

int x[5][1000];
int y[5][1000];
int sz[5];
int main() {
  while (cin >> X >> Y && X) {
    int sx, sy, gx, gy;
    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;
        }
      }
    priority_queue<NODE> Q;
    for (int i = 0; i < 5; i++) {
      Q.push(NODE(sx, sy, (i + 1) % 5, 0, i));
    }
    tr1::unordered_map<int, int> memo[5][5];

    while (Q.size()) {

      NODE q = Q.top();
      Q.pop();

      if (q.z == 10) {
        cout << q.fc + 1 << " " << q.cost << endl;
        goto exit;
      }
      if (memo[q.z][q.fc][(q.x << 12) | q.y] < q.cost)
        continue;
      if (q.z == q.fc) {
        Q.push(NODE(gx, gy, 10, q.cost + abs(q.x - gx) + abs(q.y - gy), q.fc));
      } else {
        for (int i = 0; i < sz[q.z]; i++) {
          NODE t =
              NODE(x[q.z][i], y[q.z][i], (q.z + 1) % 5,
                   q.cost + abs(q.x - x[q.z][i]) + abs(q.y - y[q.z][i]), q.fc);
          if (!memo[t.z][t.fc].count((t.x << 12) | t.y) ||
              t.cost < memo[t.z][t.fc][(t.x << 12) | t.y])
            memo[t.z][t.fc][(t.x << 12) | t.y] = t.cost, Q.push(t);
        }
      }
    }
    cout << "NA" << endl;
  exit:;
  }
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cstdio>
#include <iostream>
#include <queue>
#include <tr1/unordered_map>
#include <vector>
using namespace std;

int X, Y;
struct NODE {
  int x, y, z, cost, fc;
  NODE(int x, int y, int z, int cost, int fc)
      : x(x), y(y), z(z), cost(cost), fc(fc) {}
};
bool operator<(const NODE &a, const NODE &b) {
  return a.cost != b.cost ? a.cost > b.cost : a.fc > b.fc;
}

int x[5][1000];
int y[5][1000];
int sz[5];
int main() {
  while (cin >> X >> Y && X) {
    int sx, sy, gx, gy;
    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;
        }
      }
    priority_queue<NODE> Q;
    for (int i = 0; i < 5; i++) {
      Q.push(NODE(sx, sy, (i + 1) % 5, 0, i));
    }
    tr1::unordered_map<int, int> memo[5][5];

    while (Q.size()) {

      NODE q = Q.top();
      Q.pop();
      if (q.z == 10) {
        cout << q.fc + 1 << " " << q.cost << endl;
        goto exit;
      }
      if (q.z == q.fc) {
        Q.push(NODE(gx, gy, 10, q.cost + abs(q.x - gx) + abs(q.y - gy), q.fc));
      } else {
        for (int i = 0; i < sz[q.z]; i++) {
          NODE t =
              NODE(x[q.z][i], y[q.z][i], (q.z + 1) % 5,
                   q.cost + abs(q.x - x[q.z][i]) + abs(q.y - y[q.z][i]), q.fc);
          if (!memo[t.z][t.fc].count((t.x << 12) | t.y) ||
              t.cost < memo[t.z][t.fc][(t.x << 12) | t.y])
            memo[t.z][t.fc][(t.x << 12) | t.y] = t.cost, Q.push(t);
        }
      }
    }
    cout << "NA" << endl;
  exit:;
  }
}