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

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <sstream>
using namespace std;

#define MAX_H 100
#define MAX_W 100

#define INF (1 << 28)

bool isdigit(string s) {
  for (int i = 0; i < s.size(); i++)
    if (!isdigit(s[i]))
      return false;
  return true;
}

int to_i(string s) {
  istringstream is(s);
  int n;
  is >> n;
  return n;
}

int w, h;
string F[MAX_H][MAX_W];
int sy, sx;
int gy, gx;

struct P {
  int y, x;
  int t;
  P(int y = 0, int x = 0) : y(y), x(x) { t = INF; }
};

int dist(const P &a, const P &b) { return abs(a.x - b.x) + abs(a.y - b.y); }

vector<P> graph[50 * 50 + 1];
int main() {
  while (cin >> w >> h, w || h) {
    for (int i = 0; i <= 50 * 50; i++)
      graph[i].clear();
    for (int i = 0; i < h; i++)
      for (int j = 0; j < w; j++)
        cin >> F[i][j];
    int n = 0;
    for (int i = 0; i < h; i++)
      for (int j = 0; j < w; j++) {
        if (isdigit(F[i][j])) {
          graph[to_i(F[i][j])].push_back(P(i, j));
          n = max(n, to_i(F[i][j]));
        }
        if (F[i][j] == "S")
          sy = i, sx = j;
        if (F[i][j] == "G")
          gy = i, gx = j;
      }
    graph[0].push_back(P(sy, sx));
    graph[0][0].t = 0;
    graph[n + 1].push_back(P(gy, gx));
    for (int i = 1; i <= n + 1; i++) {
      for (int j = 0; j < graph[i].size(); j++) {
        for (int k = 0; k < graph[i - 1].size(); k++) {
          graph[i][j].t =
              min(graph[i][j].t,
                  graph[i - 1][k].t + dist(graph[i - 1][k], graph[i][j]));
        }
      }
    }
    // for (int i = 1; i <= n+1; i++) {
    //     cout << "i = " << i << endl;
    //     for (int j = 0; j < graph[i].size(); j++) {
    //         cout << graph[i][j].t << ' ';
    //     }
    //     cout << endl;
    // }
    cout << graph[n + 1][0].t << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <sstream>
using namespace std;

#define MAX_H 100
#define MAX_W 100

bool isdigit(string s) {
  for (int i = 0; i < s.size(); i++)
    if (!isdigit(s[i]))
      return false;
  return true;
}

int to_i(string s) {
  istringstream is(s);
  int n;
  is >> n;
  return n;
}

int w, h;
string F[MAX_H][MAX_W];
int sy, sx;

struct P {
  int y, x;
  int t;
  int n;
  P(int y = 0, int x = 0, int t = 0, int n = 0) : y(y), x(x), t(t), n(n) {}
};

int dy[] = {0, 1, 0, -1};
int dx[] = {1, 0, -1, 0};

int bfs(int n) {
  queue<P> q;
  q.push(P(sy, sx, 0, 0));

  bool used[h][w][n + 1];
  memset(used, 0, sizeof(used));

  while (!q.empty()) {
    P p = q.front();
    q.pop();
    if (p.n == n && F[p.y][p.x] == "G")
      return p.t;
    for (int i = 0; i < 4; i++) {
      int ny = p.y + dy[i];
      int nx = p.x + dx[i];
      if (0 <= ny && ny < h && 0 <= nx && nx < w && !used[ny][nx][p.n]) {
        used[ny][nx][p.n] = true;
        if (to_i(F[ny][nx]) == p.n + 1)
          q.push(P(ny, nx, p.t + 1, p.n + 1));
        else {
          q.push(P(ny, nx, p.t + 1, p.n));
        }
      }
    }
  }
  return -1;
}

int main() {
  while (cin >> w >> h, w || h) {
    for (int i = 0; i < h; i++)
      for (int j = 0; j < w; j++)
        cin >> F[i][j];
    int n = 0;
    for (int i = 0; i < h; i++)
      for (int j = 0; j < w; j++) {
        if (isdigit(F[i][j]))
          n = max(n, to_i(F[i][j]));
        if (F[i][j] == "S")
          sy = i, sx = j;
      }
    cout << bfs(n) << endl;
  }
  return 0;
}