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

//
#include <algorithm>
#include <bitset>
#include <cstdio>
#include <cstdlib>
#include <iomanip>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
using namespace std;
using ll = long long;
using P = pair<ll, ll>;
#define REP(i, n) for (size_t i = 0; i < (n); ++i)

int mx[4] = {-1, 0, 1, 0};
int my[4] = {0, 1, 0, -1};

int main() {
  int H, W, Ch, Cw, Dh, Dw;
  cin >> H >> W >> Ch >> Cw >> Dh >> Dw;
  --Ch, --Cw, --Dh, --Dw;
  vector<vector<char>> S(H, vector<char>(W));
  REP(i, H) REP(j, W) cin >> S[i][j];
  vector<vector<int>> visited(
      H, vector<int>(
             W, -1)); // -1 : 未訪問 0
                      // :訪問済みかつスタートからワープして到達する回数の最小値
  queue<pair<int, int>> q;
  q.push(pair<int, int>(Ch, Cw));
  visited[Ch][Cw] = 0;
  int count = 0;
  while (true) {
    vector<pair<int, int>> grids;
    // ワープなしでたどり着けるマスを調べる
    while (!q.empty()) {
      pair<int, int> cur = q.front();
      q.pop();
      int curx = cur.first;
      int cury = cur.second;
      grids.push_back(cur);
      for (int i = 0; i < 4; ++i) {
        int nx = curx + mx[i];
        int ny = cury + my[i];
        if (nx >= 0 && nx < H && ny >= 0 && ny < W && S[nx][ny] == '.' &&
            visited[nx][ny] == -1) {
          visited[nx][ny] = count;
          // ゴールにたどり着いたら走査を打ち切る
          if (nx == Dh && ny == Dw) {
            cout << visited[Dh][Dw] << endl;
            return 0;
          }
          q.push(pair<int, int>(nx, ny));
        }
      }
    }

    // ワープなしでたどり着くことのできるマスから、
    // ワープしなければたどり着けないマスを列挙し、queueに格納する
    ++count;
    for (const auto &cur : grids) {
      int curx = cur.first;
      int cury = cur.second;
      for (int x = curx - 2; x <= curx + 2; ++x) {
        for (int y = cury - 2; y <= cury + 2; ++y) {
          if (x >= 0 && x < H && y >= 0 && y < W && S[x][y] == '.' &&
              visited[x][y] == -1) {
            visited[x][y] = count;
            if (x == Dh && y == Dw) {
              cout << visited[Dh][Dw] << endl;
              return 0;
            }
            q.push(pair<int, int>(x, y));
          }
        }
      }
    }
    // ワープしてもゴールにたどり着けない場合
    if (q.empty()) {
      cout << -1 << endl;
      return 0;
    }
    grids.clear();
    // 上に戻り、ワープしてたどり着けるマスを起点として再び幅優先探索を行う
  }
  return 0;
}


Error: TLE

Fixed submission:

//
#include <algorithm>
#include <bitset>
#include <cstdio>
#include <cstdlib>
#include <iomanip>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
using namespace std;
using ll = long long;
using P = pair<ll, ll>;
#define REP(i, n) for (size_t i = 0; i < (n); ++i)

int mx[4] = {-1, 0, 1, 0};
int my[4] = {0, 1, 0, -1};

int main() {
  int H, W, Ch, Cw, Dh, Dw;
  cin >> H >> W >> Ch >> Cw >> Dh >> Dw;
  --Ch, --Cw, --Dh, --Dw;
  vector<vector<char>> S(H, vector<char>(W));
  REP(i, H) REP(j, W) cin >> S[i][j];
  vector<vector<int>> visited(
      H, vector<int>(
             W, -1)); // -1 : 未訪問 0
                      // :訪問済みかつスタートからワープして到達する回数の最小値
  queue<pair<int, int>> q;
  q.push(pair<int, int>(Ch, Cw));
  visited[Ch][Cw] = 0;
  int count = 0;
  while (true) {
    vector<pair<int, int>> grids;
    // ワープなしでたどり着けるマスを調べる
    while (!q.empty()) {
      pair<int, int> cur = q.front();
      q.pop();
      int curx = cur.first;
      int cury = cur.second;
      visited[curx][cury] = count;
      // ゴールにたどり着いたら走査を打ち切る
      if (curx == Dh && cury == Dw) {
        cout << visited[Dh][Dw] << endl;
        return 0;
      }
      grids.push_back(cur);
      for (int i = 0; i < 4; ++i) {
        int nx = curx + mx[i];
        int ny = cury + my[i];
        if (nx >= 0 && nx < H && ny >= 0 && ny < W && S[nx][ny] == '.' &&
            visited[nx][ny] == -1) {
          q.push(pair<int, int>(nx, ny));
        }
      }
    }

    // ワープなしでたどり着くことのできるマスから、
    // ワープしなければたどり着けないマスを列挙し、queueに格納する
    for (const auto &cur : grids) {
      int curx = cur.first;
      int cury = cur.second;
      for (int x = curx - 2; x <= curx + 2; ++x) {
        for (int y = cury - 2; y <= cury + 2; ++y) {
          if (x >= 0 && x < H && y >= 0 && y < W && S[x][y] == '.' &&
              visited[x][y] == -1) {
            q.push(pair<int, int>(x, y));
          }
        }
      }
    }
    // ワープしてもゴールにたどり着けない場合
    if (q.empty()) {
      cout << -1 << endl;
      return 0;
    }
    grids.clear();
    ++count;
    // 上に戻り、ワープしてたどり着けるマスを起点として再び幅優先探索を行う
  }
  return 0;
}