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

#include <algorithm>
#include <iostream>
#include <map>
#include <queue>
#include <string>
#include <utility>
#include <vector>
using namespace std;
#define REP(i, n) for (int i = 0; i < (int)(n); ++i)
#define DEBUG(x) cerr << #x << " = " << x << endl
const int INF = (int)1e9;
typedef pair<int, int> P;
int manhattan(P a, P b) {
  return abs(a.first - b.first) + abs(a.second - b.second);
}
int dp[5][1000];
int main() {
  ios::sync_with_stdio(false);
  while (true) {
    int X, Y;
    cin >> X >> Y;
    if (X == 0 && Y == 0)
      break;
    P sp, gp;
    vector<vector<P>> mp(5);
    REP(i, Y) {
      string F;
      cin >> F;
      REP(j, X) {
        if (F[j] == 'S') {
          sp = P(i, j);
        }
        if (F[j] == 'G') {
          gp = P(i, j);
        }
        if (isdigit(F[j])) {
          int id = F[j] - '0';
          mp[id - 1].push_back(P(i, j));
        }
      }
    }
    P ans(INF, INF);
    REP(i, 5) {
      REP(j, 5) REP(k, 1000) dp[j][k] = INF;
      int begin = (i + 1) % 5;
      REP(k, mp[begin].size()) { dp[begin][k] = manhattan(sp, mp[begin][k]); }
      for (int j = 2; j <= 4; ++j) {
        int prev = (i + j - 1) % 5;
        int next = (i + j) % 5;
        REP(k, mp[prev].size()) {
          REP(l, mp[next].size()) {
            int d = dp[prev][k] + manhattan(mp[prev][k], mp[next][l]);
            dp[next][l] = min(dp[next][l], d);
          }
        }
      }
      int end = (i + 4) % 5;
      REP(k, mp[end].size()) {
        ans = min(ans, make_pair(dp[end][k] + manhattan(mp[end][k], gp), i));
      }
    }
    if (ans.first == INF) {
      cout << "NA" << endl;
    } else {
      cout << ans.second + 1 << ' ' << ans.first << endl;
    }
  }
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <iostream>
#include <map>
#include <memory>
#include <queue>
#include <string>
#include <utility>
#include <vector>
using namespace std;
#define REP(i, n) for (int i = 0; i < (int)(n); ++i)
#define DEBUG(x) cerr << #x << " = " << x << endl
const int INF = (int)1e9;
typedef pair<int, int> P;
int manhattan(P a, P b) {
  return abs(a.first - b.first) + abs(a.second - b.second);
}
int main() {
  ios::sync_with_stdio(false);
  while (true) {
    int X, Y;
    cin >> X >> Y;
    if (X == 0 && Y == 0)
      break;
    P sp, gp;
    vector<vector<P>> mp(5);
    REP(i, Y) {
      string F;
      cin >> F;
      REP(j, X) {
        if (F[j] == 'S') {
          sp = P(i, j);
        }
        if (F[j] == 'G') {
          gp = P(i, j);
        }
        if (isdigit(F[j])) {
          int id = F[j] - '0';
          mp[id - 1].push_back(P(i, j));
        }
      }
    }
    P ans(INF, INF);
    REP(i, 5) {
      map<P, int> prev;
      for (P q : mp[(i + 1) % 4]) {
        prev[q] = manhattan(sp, q);
      }
      for (int j = 2; j <= 4; ++j) {
        map<P, int> next;
        for (auto p : prev) {
          for (P q : mp[(i + j) % 5]) {
            int d = p.second + manhattan(p.first, q);
            if (!next.count(q) || next[q] > d) {
              next[q] = d;
            }
          }
        }
        prev = std::move(next);
      }
      for (auto p : prev) {
        ans = min(ans, make_pair(p.second + manhattan(p.first, gp), i));
      }
    }
    if (ans.first == INF) {
      cout << "NA" << endl;
    } else {
      cout << ans.second + 1 << ' ' << ans.first << endl;
    }
  }
}