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

#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define rep(i, n) for (int i = 0; i < n; i++)
using namespace std;

struct st {
  int p, a, c, s;
};
bool operator<(st a, st b) { return a.c > b.c; }
int d[5001][1 << 5][5], x[5001], y[5001], len[5], t[5][1001];
char c[1001];

int main() {
  int w, h;
  while (scanf("%d%d", &w, &h), w) {
    int sx, sy, gx, gy, s = 0;
    memset(len, 0, sizeof(len));
    memset(d, 0x3f, sizeof(d));
    priority_queue<st> que;
    rep(i, h) {
      scanf("%s", c);
      rep(j, w) {
        if ('1' <= c[j] && c[j] <= '5') {
          c[j] -= '1';
          len[c[j]]++;
          t[c[j]][len[c[j]]] = ++s;
          x[s] = i;
          y[s] = j;
        }
        if (c[j] == 'S') {
          x[0] = i;
          y[0] = j;
          rep(k, 5) {
            d[0][1 << k][k] = 0;
            que.push({0, 1 << k, 0, k});
          }
        }
        if (c[j] == 'G')
          gx = i, gy = j;
      }
    }
    while (!que.empty()) {
      st p = que.top();
      que.pop();
      if (d[p.p][p.a][p.s] != p.c)
        continue;
      rep(i, 5) {
        if ((p.a >> i & 1) || !(p.a >> ((i + 4) % 5) & 1))
          continue;
        for (int j = 1; j <= len[i]; j++) {
          int &o = d[t[i][j]][p.a | 1 << i][p.s],
              u = p.c + abs(x[p.p] - x[t[i][j]]) + abs(y[p.p] - y[t[i][j]]);
          if (o > u) {
            o = u;
            que.push({t[i][j], p.a | 1 << i, o, p.s});
          }
        }
      }
    }
    int Min = INF, id;
    rep(i, s + 1) {
      rep(j, 5) {
        int cost = d[i][(1 << 5) - 1][j] + abs(x[i] - gx) + abs(y[i] - gy);
        if (cost < Min)
          Min = cost, id = j + 1;
        else if (cost == Min)
          id = min(id, j + 1);
      }
    }
    if (Min == INF)
      puts("NA");
    else
      printf("%d %d\\n", id, Min);
  }
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define rep(i, n) for (int i = 0; i < n; i++)
using namespace std;

struct st {
  int p, a, c, s;
};
bool operator<(st a, st b) { return a.c > b.c; }
int d[5000][1 << 5][5], x[5000], y[5000], t[5000];
int dx[]{1, -1, 0, 0}, dy[]{0, 0, 1, -1}, len;
char c[1001];

int main() {
  int w, h;
  while (scanf("%d%d", &w, &h), w) {
    int gx, gy;
    len = 0;
    x[0] = 0;
    y[0] = 0;
    rep(i, h) {
      scanf("%s", c);
      rep(j, w) {
        if ('1' <= c[j] && c[j] <= '5') {
          len++;
          x[len] = i;
          y[len] = j;
          t[len] = c[j] - '1';
        }
        if (c[j] == 'S')
          x[0] = i, y[0] = j;
        if (c[j] == 'G')
          gx = i, gy = j;
      }
    }
    memset(d, 0x3f, sizeof(d));
    priority_queue<st> que;
    rep(i, 5) {
      d[0][1 << i][i] = 0;
      que.push({0, 1 << i, 0, i});
    }
    while (!que.empty()) {
      st p = que.top();
      que.pop();
      if (d[p.p][p.a][p.s] != p.c)
        continue;
      for (int i = 1; i <= len; i++) {
        if ((p.a >> ((t[i] + 4) % 5) & 1) && (!(p.a >> t[i] & 1))) {
          int &o = d[i][p.a | 1 << t[i]][p.s],
              u = p.c + abs(x[p.p] - x[i]) + abs(y[p.p] - y[i]);
          if (o > u) {
            o = u;
            que.push({i, p.a | 1 << t[i], o, p.s});
            rep(i, 1 << 5) {
              if ((t[i] | i) == t[i] && d[p.p][i][p.s] > o)
                d[p.p][i][p.s] = o;
            }
          }
        }
      }
    }
    int Min = INF, id;
    rep(i, len + 1) {
      rep(j, 5) {
        int cost = d[i][(1 << 5) - 1][j] + abs(x[i] - gx) + abs(y[i] - gy);
        if (cost < Min)
          Min = cost, id = j + 1;
        else if (cost == Min)
          id = min(id, j + 1);
      }
    }
    if (Min == INF)
      puts("NA");
    else
      printf("%d %d\\n", id, Min);
  }
}