Problem p03053 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <cmath>
#include <iostream>
#include <limits>
#include <string>
#include <vector>

struct Point {
  int x;
  int y;

  Point(int x, int y) : x(x), y(y) {}
};

struct Cell {
  char c;
  int count;

  Cell() : c{' '}, count{std::numeric_limits<decltype(count)>::max()} {}

  bool update_count(int count) {
    if (count < this->count) {
      this->count = count;
      return true;
    } else {
      return false;
    }
  }
};

using Points = std::vector<Point>;
using Row = std::vector<Cell>;
using Board = std::vector<Row>;

bool update(Board &board, const Point &black, int r) {
  const int y_max = board.size();
  const int x_max = board.front().size();

  bool is_updated = false;
  const auto x_first = std::max(black.x - r, 0);
  const auto x_last = std::min(black.x + r + 1, x_max);
  if (black.y - r >= 0) {
    for (int x = x_first; x < x_last; ++x) {
      if (board[black.y - r][x].update_count(r + std::abs(black.x - x))) {
        is_updated = true;
      }
    }
  }
  if (black.y + r < y_max) {
    for (int x = x_first; x < x_last; ++x) {
      if (board[black.y + r][x].update_count(r + std::abs(black.x - x))) {
        is_updated = true;
      }
    }
  }

  const auto y_first = std::max(black.y - r + 1, 0);
  const auto y_last = std::min(black.y + r, y_max);
  if (black.x - r >= 0) {
    for (int y = y_first; y < y_last; ++y) {
      if (board[y][black.x - r].update_count(r + std::abs(black.y - y))) {
        is_updated = true;
      }
    }
  }
  if (black.x + r < x_max) {
    for (int y = y_first; y < y_last; ++y) {
      if (board[y][black.x + r].update_count(r + std::abs(black.y - y))) {
        is_updated = true;
      }
    }
  }

  return is_updated;
}

int solve(Board &board, Points blacks) {
  for (int i = 1; !blacks.empty(); ++i) {
    for (auto it = blacks.rbegin(); it != blacks.rend(); ++it) {
      if (!update(board, *it, i)) {
        blacks.erase((it + 1).base());
      }
    }
  }

  int result = 0;
  for (const auto &v : board) {
    const auto it = std::max_element(
        v.begin(), v.end(),
        [](const Cell &lhs, const Cell &rhs) { return lhs.count < rhs.count; });
    result = std::max(result, it->count);
  }
  return result;
}

int main() {
  int h, w;
  std::cin >> h >> w;

  Board board(h, Row(w));
  Points blacks;
  for (int i = 0; i < h; ++i) {
    for (int j = 0; j < w; ++j) {
      std::cin >> board[i][j].c;
      if (board[i][j].c == '#') {
        board[i][j].count = 0;
        blacks.emplace_back(j, i);
      }
    }
  }

  std::cout << solve(board, blacks) << std::endl;
}


Fixed submission:
#include <algorithm>
#include <cmath>
#include <iostream>
#include <limits>
#include <string>
#include <vector>

struct Point {
  int x;
  int y;

  Point(int x, int y) : x(x), y(y) {}
};

struct Cell {
  char c;
  int count;

  Cell() : c{' '}, count{std::numeric_limits<decltype(count)>::max()} {}

  bool update_count(int count) {
    if (count < this->count) {
      this->count = count;
      return true;
    } else {
      return false;
    }
  }
};

using Points = std::vector<Point>;
using Row = std::vector<Cell>;
using Board = std::vector<Row>;

bool update(Board &board, const Point &black, int r) {
  const int y_max = board.size();
  const int x_max = board.front().size();

  bool is_updated = false;
  const auto x_first = std::max(black.x - r, 0);
  const auto x_last = std::min(black.x + r + 1, x_max);
  if (black.y - r >= 0) {
    for (int x = x_first; x < x_last; ++x) {
      if (board[black.y - r][x].update_count(r + std::abs(black.x - x))) {
        is_updated = true;
      }
    }
  }
  if (black.y + r < y_max) {
    for (int x = x_first; x < x_last; ++x) {
      if (board[black.y + r][x].update_count(r + std::abs(black.x - x))) {
        is_updated = true;
      }
    }
  }

  const auto y_first = std::max(black.y - r + 1, 0);
  const auto y_last = std::min(black.y + r, y_max);
  if (black.x - r >= 0) {
    for (int y = y_first; y < y_last; ++y) {
      if (board[y][black.x - r].update_count(r + std::abs(black.y - y))) {
        is_updated = true;
      }
    }
  }
  if (black.x + r < x_max) {
    for (int y = y_first; y < y_last; ++y) {
      if (board[y][black.x + r].update_count(r + std::abs(black.y - y))) {
        is_updated = true;
      }
    }
  }

  return is_updated;
}

int solve(Board &board, Points blacks) {
  const auto first = blacks.begin();
  auto last = blacks.end();
  for (int i = 1; first != last; ++i) {
    last = std::remove_if(first, last, [&board, i](const Point &p) {
      return !update(board, p, i);
    });
  }

  int result = 0;
  for (const auto &v : board) {
    const auto it = std::max_element(
        v.begin(), v.end(),
        [](const Cell &lhs, const Cell &rhs) { return lhs.count < rhs.count; });
    result = std::max(result, it->count);
  }
  return result;
}

int main() {
  int h, w;
  std::cin >> h >> w;

  Board board(h, Row(w));
  Points blacks;
  for (int i = 0; i < h; ++i) {
    for (int j = 0; j < w; ++j) {
      std::cin >> board[i][j].c;
      if (board[i][j].c == '#') {
        board[i][j].count = 0;
        blacks.emplace_back(j, i);
      }
    }
  }

  std::cout << solve(board, blacks) << std::endl;
}