Problem p03053 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <bitset>
#include <iomanip>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stdint.h>
#include <string>
#include <vector>

using namespace std;

#define PI (3.14159265358979323846)
#define INF (2147483647)
#define INF_LL (9223372036854775807)
#define DIV_NUM (1000000007)

// BFSによる塗りつぶし探索(多地点スタート形式)
#define MAX_H (50)
#define MAX_W (50)
typedef char Graph[MAX_H][MAX_W];
Graph graph;
typedef int Dist[MAX_H][MAX_W];
Dist dist;
bool seen[MAX_H][MAX_W];
int H, W; // グラフサイズ
typedef pair<int, int> P;

// 指定されたマスが次のdfsを行う対象かどうかをチェックする関数
// 0 <= h < H, 0 <= w < W を満たすこと
// その他追加条件を満たすこと　を確認
bool willCheck(int h, int w) {

  // グラフサイズ内であることの確認
  if (h < 0)
    return false;
  if (w < 0)
    return false;
  if (H <= h)
    return false;
  if (W <= w)
    return false;

  // 既に探索済みでないことの確認
  if (seen[h][w])
    return false;

  // 問題ごとの条件を満たす確認
  if (graph[h][w] == '.')
    return true;

  return false;
}

void bfs(vector<P> start) {
  // キューを用意して、初期探索点をセット
  queue<P> que;
  for (int i = 0; i < start.size(); i++) {
    que.push(P(start[i].first, start[i].second)); // 初期点の距離を0
    dist[start[i].first][start[i].second] = 0;
    seen[start[i].first][start[i].second] = true;
  }

  while (!que.empty()) { // BFSループ
    // ★★　この中で迂闊に break しないこと

    // キューの先頭のセルを取得
    P v = que.front();
    que.pop();
    int h = v.first;
    int w = v.second;

    // 取得したセルに対する処理

    // そのセルからつながるセルに処理を移行
    if (willCheck(h + 1, w)) {
      dist[h + 1][w] = dist[h][w] + 1;
      seen[h + 1][w] =
          true; // ここでseenをセットしないと、queに同一アイテムが入る
      que.push(P(h + 1, w));
    }
    if (willCheck(h - 1, w)) {
      dist[h - 1][w] = dist[h][w] + 1;
      seen[h - 1][w] = true;
      que.push(P(h - 1, w));
    }
    if (willCheck(h, w + 1)) {
      dist[h][w + 1] = dist[h][w] + 1;
      seen[h][w + 1] = true;
      que.push(P(h, w + 1));
    }
    if (willCheck(h, w - 1)) {
      dist[h][w - 1] = dist[h][w] + 1;
      seen[h][w - 1] = true;
      que.push(P(h, w - 1));
    }
  }
}

int main() {

  cin >> H >> W;

  vector<P> start;
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      char tmp;
      cin >> tmp;
      graph[i][j] = tmp;
      if (tmp == '#')
        start.push_back(P(i, j));
    }
  }

  bfs(start);

  int ans = 0;
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      ans = max(ans, dist[i][j]);
    }
  }

  cout << ans << endl;

  return 0;
}

Fixed submission:
#include <algorithm>
#include <bitset>
#include <iomanip>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stdint.h>
#include <string>
#include <vector>

using namespace std;

#define PI (3.14159265358979323846)
#define INF (2147483647)
#define INF_LL (9223372036854775807)
#define DIV_NUM (1000000007)

// BFSによる塗りつぶし探索(多地点スタート形式)
#define MAX_H (1000)
#define MAX_W (1000)
typedef char Graph[MAX_H][MAX_W];
Graph graph;
typedef int Dist[MAX_H][MAX_W];
Dist dist;
bool seen[MAX_H][MAX_W];
int H, W; // グラフサイズ
typedef pair<int, int> P;

// 指定されたマスが次のdfsを行う対象かどうかをチェックする関数
// 0 <= h < H, 0 <= w < W を満たすこと
// その他追加条件を満たすこと　を確認
bool willCheck(int h, int w) {

  // グラフサイズ内であることの確認
  if (h < 0)
    return false;
  if (w < 0)
    return false;
  if (H <= h)
    return false;
  if (W <= w)
    return false;

  // 既に探索済みでないことの確認
  if (seen[h][w])
    return false;

  // 問題ごとの条件を満たす確認
  if (graph[h][w] == '.')
    return true;

  return false;
}

void bfs(vector<P> start) {
  // キューを用意して、初期探索点をセット
  queue<P> que;
  for (int i = 0; i < start.size(); i++) {
    que.push(P(start[i].first, start[i].second)); // 初期点の距離を0
    dist[start[i].first][start[i].second] = 0;
    seen[start[i].first][start[i].second] = true;
  }

  while (!que.empty()) { // BFSループ
    // ★★　この中で迂闊に break しないこと

    // キューの先頭のセルを取得
    P v = que.front();
    que.pop();
    int h = v.first;
    int w = v.second;

    // 取得したセルに対する処理

    // そのセルからつながるセルに処理を移行
    if (willCheck(h + 1, w)) {
      dist[h + 1][w] = dist[h][w] + 1;
      seen[h + 1][w] =
          true; // ここでseenをセットしないと、queに同一アイテムが入る
      que.push(P(h + 1, w));
    }
    if (willCheck(h - 1, w)) {
      dist[h - 1][w] = dist[h][w] + 1;
      seen[h - 1][w] = true;
      que.push(P(h - 1, w));
    }
    if (willCheck(h, w + 1)) {
      dist[h][w + 1] = dist[h][w] + 1;
      seen[h][w + 1] = true;
      que.push(P(h, w + 1));
    }
    if (willCheck(h, w - 1)) {
      dist[h][w - 1] = dist[h][w] + 1;
      seen[h][w - 1] = true;
      que.push(P(h, w - 1));
    }
  }
}

int main() {

  cin >> H >> W;

  vector<P> start;
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      char tmp;
      cin >> tmp;
      graph[i][j] = tmp;
      if (tmp == '#')
        start.push_back(P(i, j));
    }
  }

  bfs(start);

  int ans = 0;
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      ans = max(ans, dist[i][j]);
    }
  }

  cout << ans << endl;

  return 0;
}