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

#define _GLIBCXX_DEBUG
#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define ll long long
#define all(x) (x).begin(), (x).end()
template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <class T> bool chmin(T &a, const T &b) {
  if (b < a) {
    a = b;
    return 1;
  }
  return 0;
}
const ll INF = 1000000000000;

typedef pair<ll, ll> P;

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

  ll ch, cw, dh, dw;
  cin >> ch >> cw;
  cin >> dh >> dw;
  ch--;
  cw--;
  dh--;
  dw--;

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

  vector<string> shw(H);
  for (ll i = 0; i < H; i++)
    cin >> shw[i];

  // 全探索して
  vector<vector<ll>> d(H, vector<ll>(W)); // 距離の配列
  vector<vector<bool>> checked(H, vector<bool>(W));
  vector<vector<bool>> queued(H, vector<bool>(W));
  for (ll i = 0; i < H; i++) {
    for (ll j = 0; j < W; j++) {
      d[i][j] = INF;
    }
  }
  deque<P> que;
  d[ch][cw] = 0;

  que.push_front(P(ch, cw));
  queued[ch][cw] = true;
  // O(HW*25) = O(HW)
  while (que.size()) {
    P p = que.front();
    que.pop_front();
    // あるいて行ける場合
    for (ll i = 0; i < 4; i++) {
      ll ny = p.first + dy[i];
      ll nx = p.second + dx[i];

      if (0 <= ny and ny < H and 0 <= nx and nx < W and shw[ny][nx] == '.') {
        if (not queued[ny][nx]) {
          que.push_front(P(ny, nx));
          queued[ny][nx] = true;
        }
        d[ny][nx] = d[p.first][p.second];
      }
    }
    // 魔法を使う場合
    for (ll i = -2; i < 3; i++) {
      for (ll j = -2; j < 3; j++) {
        ll ny = p.first + i;
        ll nx = p.second + j;
        if (i == 0 and j == 0)
          continue;

        if (0 <= nx and nx < W and 0 <= ny and ny < H and shw[ny][nx] == '.') {
          // 現状見つかってるルートよりも，このワープのほうが効率的な場合
          if (d[ny][nx] > d[p.first][p.second] + 1) {
            que.push_back(P(ny, nx));
            d[ny][nx] = d[p.first][p.second] + 1;
          }
        }
      }
    }
  }
  ll ans = 0;
  if (d[dh][dw] == INF)
    ans = -1;
  else
    ans = d[dh][dw];

  cout << ans << endl;
}

Error: TLE

Fixed submission:

#define _GLIBCXX_DEBUG
#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define ll long long
#define all(x) (x).begin(), (x).end()
template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <class T> bool chmin(T &a, const T &b) {
  if (b < a) {
    a = b;
    return 1;
  }
  return 0;
}
const int INF = 1000000000;

typedef pair<int, int> P;

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

  int ch, cw, dh, dw;
  cin >> ch >> cw;
  cin >> dh >> dw;
  ch--;
  cw--;
  dh--;
  dw--;

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

  vector<string> shw(H);
  for (int i = 0; i < H; i++)
    cin >> shw[i];

  // 全探索して
  vector<vector<int>> d(H, vector<int>(W)); // 距離の配列
  vector<vector<bool>> checked(H, vector<bool>(W));
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      d[i][j] = INF;
    }
  }
  queue<P> que;
  d[ch][cw] = 0;

  que.push(P(ch, cw));
  // O(HW*25) = O(HW)
  while (que.size()) {
    P p = que.front();
    que.pop();
    checked[p.first][p.second] = true;
    for (int i = 0; i < 4; i++) {
      int ny = p.first + dx[i], nx = p.second + dy[i];

      if (0 <= ny and ny < H and 0 <= nx and nx < W and shw[ny][nx] == '.') {
        if (not checked[ny][nx] and not(ny == p.first and nx == p.second))
          que.push(P(ny, nx));
        chmin(d[ny][nx], d[p.first][p.second]);
      }
    }

    for (int i = -2; i < 3; i++) {
      for (int j = -2; j < 3; j++) {
        int ny = p.first + i;
        int nx = p.second + j;
        if (0 <= nx and nx < W and 0 <= ny and ny < H and shw[ny][nx] == '.') {
          if (not checked[ny][nx] and not(ny == p.first and nx == p.second))
            que.push(P(ny, nx));
          chmin(d[ny][nx], d[p.first][p.second] + 1);
        }
      }
    }
  }

  if (d[dh][dw] == INF)
    cout << -1 << endl;
  else
    cout << d[dh][dw] << endl;
}