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

#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
using ll = long long;
using P = pair<int, int>;

int h, w;
int ch, cw;
int dh, dw;
vector<vector<int>> s;
vector<vector<int>> visited;
vector<int> dx = {-1, 1, 0, 0, 0};
vector<int> dy = {0, 0, 0, 1, -1};

bool is_can(int ny, int nx) {
  if (nx <= 0 || nx > w || ny <= 0 || ny > h) {
    return false;
  }
  if (s[ny][nx] == 1) {
    return false;
  }
  return true;
}

int main() {
  cin >> h >> w;
  s.resize(h + 1, vector<int>(w + 1, 0));
  visited.resize(h + 1, vector<int>(w + 1, -1));
  cin >> ch >> cw;
  cin >> dh >> dw;

  rep(i, h) {
    rep(j, w) {
      char a;
      cin >> a;
      if (a == '.') {
        s[i + 1][j + 1] = 0;
      } else {
        s[i + 1][j + 1] = 1;
      }
    }
  }

  int ans = -1;

  // ワープX回目での到達可能距離
  queue<P> que;
  queue<P> cur_que;

  que.push(P(ch, cw));

  int warp = 0;
  while (true) {
    bool finished = false;

    while (!que.empty()) {
      auto p = que.front();
      que.pop();

      int y = p.first;
      int x = p.second;
      // cout << warp << ": " << y << "," << x << endl;
      for (int i = 0; i < 5; i++) {
        int nx = x + dx[i];
        int ny = y + dy[i];
        if (is_can(ny, nx) && visited[ny][nx] == -1) {
          que.push(P(ny, nx));
          cur_que.push(P(ny, nx));
          visited[ny][nx] = warp;
          if (P(ny, nx) == P(dh, dw)) {
            ans = warp;
            finished = true;
          }
        }
      }
    }

    if (finished) {
      break;
    }

    // ワープ
    queue<P> next_que;
    while (!cur_que.empty()) {
      auto p = cur_que.front();
      int y = p.first;
      int x = p.second;
      cur_que.pop();

      for (int wx = -2; wx <= 2; wx++) {
        for (int wy = -2; wy <= 2; wy++) {
          int nx = x + wx;
          int ny = y + wy;
          if (is_can(ny, nx) && visited[ny][nx] == -1) {
            next_que.push(P(ny, nx));
          }
        }
      }
    }

    if (next_que.size() == 0) {
      break;
    }
    que = next_que;
    warp++;
  }

  cout << ans << endl;
  return 0;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
using ll = long long;
using P = pair<int, int>;

int h, w;
int ch, cw;
int dh, dw;
set<P> can;
vector<int> dx = {-1, 1, 0, 0, 0};
vector<int> dy = {0, 0, 0, 1, -1};

bool is_can(int ny, int nx) {
  if (can.find(P(ny, nx)) == can.end()) {
    return false;
  }
  if (nx <= 0 || nx > w || ny <= 0 || ny > h) {
    return false;
  }
  return true;
}

int main() {
  cin >> h >> w;
  cin >> ch >> cw;
  cin >> dh >> dw;

  rep(i, h) {
    rep(j, w) {
      char a;
      cin >> a;
      if (a == '.') {
        can.insert(P(i + 1, j + 1));
      }
    }
  }

  int ans = -1;

  // ワープX回目での到達可能距離
  set<P> visited;
  queue<P> que;
  queue<P> cur_que;

  // dh,dw に到達可能かどうかを判定する
  bool can_d = false;
  for (int wx = -2; wx <= 2; wx++) {
    for (int wy = -2; wy <= 2; wy++) {
      int nx = cw + wx;
      int ny = ch + wy;
      if (is_can(ny, nx)) {
        can_d = true;
      }
    }
  }
  if (!can_d) {
    cout << -1 << endl;
    return 0;
  }

  que.push(P(ch, cw));

  int warp = 0;
  while (true) {
    bool finished = false;

    while (!que.empty()) {
      auto p = que.front();
      que.pop();

      int y = p.first;
      int x = p.second;
      // cout << warp << ": " << y << "," << x << endl;
      for (int i = 0; i < 5; i++) {
        int nx = x + dx[i];
        int ny = y + dy[i];
        if (visited.find(P(ny, nx)) == visited.end() && is_can(ny, nx)) {
          que.push(P(ny, nx));
          cur_que.push(P(ny, nx));
          visited.insert(P(ny, nx));
          if (P(ny, nx) == P(dh, dw)) {
            ans = warp;
            finished = true;
          }
        }
      }
    }

    if (finished) {
      break;
    }

    // ワープ
    queue<P> next_que;
    while (!cur_que.empty()) {
      auto p = cur_que.front();
      int y = p.first;
      int x = p.second;
      cur_que.pop();

      for (int wx = -2; wx <= 2; wx++) {
        for (int wy = -2; wy <= 2; wy++) {
          int nx = x + wx;
          int ny = y + wy;
          if (visited.find(P(ny, nx)) == visited.end() && is_can(ny, nx)) {
            next_que.push(P(ny, nx));
          }
        }
      }
    }

    if (next_que.size() == 0) {
      break;
    }
    que = next_que;
    warp++;
  }

  cout << ans << endl;
  return 0;
}