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

// https://atcoder.jp/contests/abc176/tasks/abc176_d
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define REP(i, n) FOR(i, 0, n)
#define FOR(i, s, n) for (int i = (s), i##_len = (n); i < i##_len; ++i)
#define ALL(obj) (obj).begin(), (obj).end()
#define ALLR(obj) (obj).rbegin(), (obj).rend()
#define CEIL(a, b) ((a - 1) / b + 1)

pair<int, int> mv[4] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
const int INF = 1e15;

void solve() {
  int H, W, CH, CW, DH, DW;
  cin >> H >> W >> CH >> CW >> DH >> DW;
  CH--, CW--, DH--, DW--;
  vector<string> v(H);
  REP(i, H) { cin >> v[i]; }
  // ワープ回数の最小値を記録
  vector<vector<int>> dist(H, vector<int>(W, INF));
  // 歩いた場所を記録（ワープ先では記録しない）
  // vector<vector<bool>> visited(H, vector<bool>(W));
  // visited[CH][CW] = true;
  dist[CH][CW] = 0;
  // ワープ回数、H, W,
  priority_queue<tuple<int, int, int>> q;
  q.push({0, CH, CW});

  while (!q.empty()) {
    auto now = q.top();
    q.pop();
    int from_h, from_w, from_wp;
    tie(from_wp, from_h, from_w) = now;
    from_wp = -from_wp;
    if (from_h == DH && from_w == DW) {
      cout << from_wp << endl;
      return;
    }
    for (auto x : mv) {
      int next_h = from_h + x.first;
      int next_w = from_w + x.second;
      // 範囲外なら処理しない
      if (next_h < 0 || next_h >= H || next_w < 0 || next_w >= W) {
        continue;
      }
      // if (abs(DH - next_h) > abs(DH - from_h) ||
      //     abs(DW - next_w) > abs(DW - from_w)) {
      //     continue;
      // }
      // 壁ならワープする
      if (v[next_h][next_w] == '#') {
        FOR(r, max(0LL, from_h - 2), min(H, from_h + 3)) {
          FOR(c, max(0LL, from_w - 2), min(W, from_w + 3)) {
            if (r == from_h && c == from_w) {
              continue;
            }
            // 宛先のワープ回数
            int wp_to = dist[r][c];
            // ワープ先が壁ではない
            if (v[r][c] != '#' && from_wp + 1 < wp_to) {
              dist[r][c] = from_wp + 1;
              q.push({-(from_wp + 1), r, c});
            }
          }
        }
      } else {
        // ワープ回数が現在地より多い
        if (dist[next_h][next_w] > from_wp) {
          // 壁以外なら普通に進む
          q.push({-from_wp, next_h, next_w});
          dist[next_h][next_w] = from_wp;
        }
      }
    }
  }
  if (dist[DH][DW] == INF) {
    cout << "-1\\n";
  } else {
    cout << dist[DH][DW] << endl;
  }
}

signed main() {
  cin.tie(nullptr)->sync_with_stdio(false);
  solve();
}


Error: TLE

Fixed submission:

// https://atcoder.jp/contests/abc176/tasks/abc176_d
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define REP(i, n) FOR(i, 0, n)
#define FOR(i, s, n) for (int i = (s), i##_len = (n); i < i##_len; ++i)
#define ALL(obj) (obj).begin(), (obj).end()
#define ALLR(obj) (obj).rbegin(), (obj).rend()
#define CEIL(a, b) ((a - 1) / b + 1)

pair<int, int> mv[4] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
const int INF = 1e15;

void solve() {
  int H, W, CH, CW, DH, DW;
  cin >> H >> W >> CH >> CW >> DH >> DW;
  CH--, CW--, DH--, DW--;
  vector<string> v(H);
  REP(i, H) { cin >> v[i]; }
  // ワープ回数の最小値を記録
  vector<vector<int>> dist(H, vector<int>(W, INF));
  // 歩いた場所を記録（ワープ先では記録しない）
  // vector<vector<bool>> visited(H, vector<bool>(W));
  // visited[CH][CW] = true;
  dist[CH][CW] = 0;
  // H, W, ワープ回数
  queue<tuple<int, int, int>> q;
  q.push({CH, CW, 0});

  while (!q.empty()) {
    auto now = q.front();
    q.pop();
    int from_h, from_w, from_wp;
    tie(from_h, from_w, from_wp) = now;
    if (from_h == DH && from_w == DW) {
      // キュー追加しない
      continue;
    }
    for (auto x : mv) {
      int next_row = from_h + x.first;
      int next_col = from_w + x.second;
      // 範囲外なら処理しない
      if (next_row < 0 || next_row >= H || next_col < 0 || next_col >= W) {
        continue;
      }
      // 壁ならワープする
      if (v[next_row][next_col] == '#') {
        FOR(r, max(0LL, from_h - 2), min(H, from_h + 3)) {
          FOR(c, max(0LL, from_w - 2), min(W, from_w + 3)) {
            if (r == from_h && c == from_w) {
              continue;
            }
            // 宛先のワープ回数
            int wp_to = dist[r][c];
            // ワープ先が壁ではない
            if (v[r][c] != '#' && from_wp + 1 < wp_to) {
              dist[r][c] = from_wp + 1;
              q.push({r, c, from_wp + 1});
            }
          }
        }
      } else {
        // ワープ回数が現在地より多い
        if (dist[next_row][next_col] > from_wp) {
          // 壁以外なら普通に進む
          q.push({next_row, next_col, from_wp});
          dist[next_row][next_col] = from_wp;
        }
      }
    }
  }
  if (dist[DH][DW] == INF) {
    cout << "-1\\n";
  } else {
    cout << dist[DH][DW] << endl;
  }
}

signed main() {
  cin.tie(nullptr)->sync_with_stdio(false);
  solve();
}