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

#include <cstdlib>
#include <iostream>
#include <vector>
using namespace std;
struct P {
  int x, y, cost;
  P(int a, int b, int c) { x = a, y = b, cost = c; }
  P() {}
};
#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) { // remain
        int z = (lp + Z + 2) % 5;
        int prev = (z + 4) % 5;
        rep(i, data[prev].size()) { // prev
          rep(j, data[z].size()) {  // cur
            int cost = dp[prev][i].cost + dist(dp[prev][i], data[z][j]);
            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: TLE

Fixed submission:

#include <algorithm>
#include <cstdio>
#include <iostream>
#include <queue>
#include <tr1/unordered_map>
#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 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);
  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 ans;
}
int main() {
  while (cin >> X >> Y && X) {
    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;
  }
}