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

#include <algorithm>
#include <cstdio>
#include <iostream>
#include <queue>

using namespace std;

typedef pair<int, int> P;

const int INF = 100000000;
const int MAX_H = 1000;
const int MAX_W = 1000;
const int MAX_N = 9;

//&#36755;入
int H, W, N;
char maze[MAX_H][MAX_W + 1];

int sx, sy;
int d[MAX_H][MAX_W];

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

// 求以(sx, sy)&#20026;起点到&#36798;目&#26631;c的最短路径&#38271;度
int bfs(char c) {
  // 初始化
  for (int i = 0; i < H; i++) {
    fill(d[i], d[i] + W, INF);
  }
  d[sx][sy] = 0;
  queue<P> que;
  que.push(P(sx, sy));
  //&#23485;度&#20248;先
  while (!que.empty()) {
    P p = que.front();
    que.pop();
    // 已找到
    if (maze[p.first][p.second] == c) {
      // 重置起点
      sx = p.first;
      sy = p.second;
      break;
    }

    for (int i = 0; i < 4; i++) {
      int nx = p.first + dx[i], ny = p.second + dy[i];
      // 判断是否可移&#21160;以及是否已&#32463;&#35775;&#38382;&#36807;
      if (0 <= nx && nx < H && 0 <= ny && ny < W && maze[nx][ny] != 'X' &&
          d[nx][ny] == INF) {
        que.push(P(nx, ny));
        d[nx][ny] = d[p.first][p.second] + 1;
      }
    }
  }
  //	printf("%d, %d\\n", sx, sy);
  return d[sx][sy];
}

void solve() {
  // 找起始点
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      if (maze[i][j] == 'S') {
        sx = i;
        sy = j;
        break;
      }
    }
  }
  //&#23485;度&#20248;先搜索
  int ans = 0;
  for (int i = 1; i <= N; i++) {
    ans += bfs('0' + i);
  }
  printf("%d\\n", ans);
}

int main(int argc, char const *argv[]) {

  scanf("%d %d %d", &H, &W, &N);
  for (int i = 0; i < H; i++) {
    scanf("%s", maze[i]);
  }
  solve();

  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>

using namespace std;

typedef pair<int, int> P;

const int INF = 100000000;
const int MAX_H = 1000;
const int MAX_W = 1000;
const int MAX_N = 9;

//&#36755;入
int H, W, N;
char maze[MAX_H][MAX_W + 1];

int sx, sy;
int d[MAX_H][MAX_W];

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

// 求以(sx, sy)&#20026;起点到&#36798;目&#26631;c的最短路径&#38271;度
int bfs(char c) {
  // 初始化
  memset(d, -1, sizeof(d));
  d[sx][sy] = 0;
  queue<P> que;
  que.push(P(sx, sy));
  //&#23485;度&#20248;先
  while (!que.empty()) {
    P p = que.front();
    que.pop();
    // 已找到
    if (maze[p.first][p.second] == c) {
      // 重置起点
      sx = p.first;
      sy = p.second;
      break;
    }

    for (int i = 0; i < 4; i++) {
      int nx = p.first + dx[i], ny = p.second + dy[i];
      // 判断是否可移&#21160;以及是否已&#32463;&#35775;&#38382;&#36807;
      if (0 <= nx && nx < H && 0 <= ny && ny < W && maze[nx][ny] != 'X' &&
          d[nx][ny] == -1) {
        que.push(P(nx, ny));
        d[nx][ny] = d[p.first][p.second] + 1;
      }
    }
  }
  return d[sx][sy];
}

void solve() {
  // 找起始点
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      if (maze[i][j] == 'S') {
        sx = i;
        sy = j;
        break;
      }
    }
  }
  //&#23485;度&#20248;先搜索
  int ans = 0;
  for (int i = 1; i <= N; i++) {
    ans += bfs('0' + i);
  }
  printf("%d\\n", ans);
}

int main(int argc, char const *argv[]) {

  while (scanf("%d %d %d", &H, &W, &N)) {
    for (int i = 0; i < H; i++) {
      scanf("%s", maze[i]);
    }
    solve();
  }

  return 0;
}