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

#include <algorithm>
#include <bitset>
#include <chrono>
#include <cmath>
#include <cstdint>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>

#define N_TIMES(i, n) for (uint64_t i = 0; i < n; ++i)
#define N_TIMES_REV(i, n) for (int64_t i = n - 1; i >= 0; --i)

template <typename T>
using maximum_heap = std::priority_queue<T, std::vector<T>, std::less<T>>;
template <typename T>
using minimum_heap = std::priority_queue<T, std::vector<T>, std::greater<T>>;

template <typename T>
std::istream &operator>>(std::istream &is, std::vector<T> &v) {
  for (typename std::vector<T>::size_type i = 0; i < v.size(); ++i) {
    is >> v[i];
  }
  return is;
}

using namespace std;

struct Point {
  uint32_t y, x;
  Point(uint32_t y, uint32_t x) : y(y), x(x) {}
  bool operator==(const Point &rhs) const { return y == rhs.y && x == rhs.x; }
  bool operator<(const Point &rhs) const {
    return y == rhs.y ? x < rhs.x : y < rhs.y;
  }
};

struct QueueItem {
  Point p;
  int32_t c;

  QueueItem(const Point p, int32_t c) : p(p), c(c) {}
};

int main() {
  uint32_t H, W;
  cin >> H >> W;

  uint32_t Ch, Cw, Dh, Dw;
  cin >> Ch >> Cw >> Dh >> Dw;
  --Ch;
  --Cw;
  --Dh;
  --Dw;

  vector<string> S(H);
  N_TIMES(h, H) { cin >> S[h]; }

  vector<vector<int32_t>> P(H, vector<int32_t>(W, -1));

  const auto isInMaze = [&](const Point &p) { return p.y < H && p.x < W; };

  queue<QueueItem> q;
  q.emplace(Point(Ch, Cw), 0);
  P[Ch][Cw] = 0;
  while (!q.empty()) {
    list<Point> ps;

    while (!q.empty()) {
      QueueItem item = q.front();
      q.pop();

      const uint32_t D = 4;
      int32_t dy[D] = {-1, +1, 0, 0}, dx[D] = {0, 0, -1, +1};
      N_TIMES(d, D) {
        Point new_point(item.p.y + dy[d], item.p.x + dx[d]);
        QueueItem new_item(new_point, item.c);
        if (isInMaze(new_point) && P[new_point.y][new_point.x] < 0) {
          if (S[new_item.p.y][new_item.p.x] == '.') {
            P[new_point.y][new_point.x] = new_item.c;
            q.emplace(new_item);
          } else {
            if (P[new_point.y][new_point.x] == -1) {
              ps.push_back(item.p);
              --P[new_point.y][new_point.x];
            }
          }
        }
      }
    }

    for (const Point &p : ps) {
      for (int32_t dy = -2; dy <= +2; ++dy) {
        for (int32_t dx = -2; dx <= +2; ++dx) {
          Point new_point(p.y + dy, p.x + dx);
          QueueItem new_item(new_point, P[p.y][p.x] + 1);
          if (isInMaze(new_point) && P[new_point.y][new_point.x] < 0) {
            if (S[new_point.y][new_point.x] == '.') {
              P[new_point.y][new_point.x] = new_item.c;
              q.emplace(new_item);
            }
          }
        }
      }
    }
  }

  cout << P[Dh][Dw] << endl;

  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <bitset>
#include <chrono>
#include <cmath>
#include <cstdint>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>

#define N_TIMES(i, n) for (uint64_t i = 0; i < n; ++i)
#define N_TIMES_REV(i, n) for (int64_t i = n - 1; i >= 0; --i)

template <typename T>
using maximum_heap = std::priority_queue<T, std::vector<T>, std::less<T>>;
template <typename T>
using minimum_heap = std::priority_queue<T, std::vector<T>, std::greater<T>>;

template <typename T>
std::istream &operator>>(std::istream &is, std::vector<T> &v) {
  for (typename std::vector<T>::size_type i = 0; i < v.size(); ++i) {
    is >> v[i];
  }
  return is;
}

using namespace std;

struct Point {
  uint32_t y, x;
  Point(uint32_t y, uint32_t x) : y(y), x(x) {}
  bool operator==(const Point &rhs) const { return y == rhs.y && x == rhs.x; }
  bool operator<(const Point &rhs) const {
    return y == rhs.y ? x < rhs.x : y < rhs.y;
  }
};

struct QueueItem {
  uint32_t y, x;
  int32_t c;

  QueueItem(uint32_t y, uint32_t x, int32_t c) : y(y), x(x), c(c) {}
};

int main() {
  uint32_t H, W;
  cin >> H >> W;

  uint32_t Ch, Cw, Dh, Dw;
  cin >> Ch >> Cw >> Dh >> Dw;
  --Ch;
  --Cw;
  --Dh;
  --Dw;

  vector<string> S(H);
  N_TIMES(h, H) { cin >> S[h]; }

  vector<vector<int32_t>> P(H, vector<int32_t>(W, -1));

  const auto isInMaze = [&](const QueueItem &item) {
    return item.y < H && item.x < W;
  };

  queue<QueueItem> q;
  q.emplace(Ch, Cw, 0);
  while (!q.empty()) {
    set<Point> s;

    while (!q.empty()) {
      QueueItem item = q.front();
      q.pop();
      P[item.y][item.x] = item.c;

      const uint32_t D = 4;
      int32_t dy[D] = {-1, +1, 0, 0}, dx[D] = {0, 0, -1, +1};
      N_TIMES(d, D) {
        QueueItem new_item(item.y + dy[d], item.x + dx[d], item.c);
        if (isInMaze(new_item) && P[new_item.y][new_item.x] < 0) {
          if (S[new_item.y][new_item.x] == '.') {
            q.emplace(new_item);
          } else {
            s.emplace(item.y, item.x);
          }
        }
      }
    }

    for (const Point &p : s) {
      for (int32_t dy = -2; dy <= +2; ++dy) {
        for (int32_t dx = -2; dx <= +2; ++dx) {
          QueueItem new_item(p.y + dy, p.x + dx, P[p.y][p.x] + 1);
          if (isInMaze(new_item) && P[new_item.y][new_item.x] < 0) {
            if (S[new_item.y][new_item.x] == '.') {
              q.emplace(new_item);
            }
          }
        }
      }
    }
  }

  cout << P[Dh][Dw] << endl;

  return 0;
}