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

#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}
using P = pair<int, int>;

const int INF = 1e9;
const int N = 1010;

char board[N][N];
int dist[N][N];

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

int h, w;

bool isSafe(int x, int y) {
  if (1 <= x && x <= h && 1 <= y && y <= w && board[x][y] == '.') {
    return true;
  } else {
    return false;
  }
}

signed main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);

  cin >> h >> w;
  int ch, cw, dh, dw;
  cin >> ch >> cw >> dh >> dw;

  for (int i = 1; i <= h; i++) {
    for (int j = 1; j <= w; j++) {
      cin >> board[i][j];
    }
  }

  rep(i, N) rep(j, N) dist[i][j] = INF;

  deque<P> que;
  que.emplace_front(ch, cw);
  dist[ch][cw] = 0;

  while (!que.empty()) {
    int curx = que.front().first;
    int cury = que.front().second;
    que.pop_front();

    for (int i = 0; i < 4; i++) {
      int nx = curx + dx[i];
      int ny = cury + dy[i];
      if (!isSafe(nx, ny))
        continue;
      if (dist[nx][ny] <= dist[curx][cury])
        continue;

      dist[nx][ny] = dist[curx][cury];
      que.emplace_front(nx, ny);
    }

    for (int i = -2; i <= 2; i++) {
      for (int j = -2; j <= 2; j++) {
        int nx = curx + i;
        int ny = cury + j;
        if (!isSafe(nx, ny))
          continue;
        if (dist[nx][ny] <= dist[curx][cury] + 1)
          continue;
        dist[nx][ny] = dist[curx][cury] + 1;
        que.emplace_back(nx, ny);
      }
    }
  }
  int ans = dist[dh][dw];
  if (ans == INF)
    ans = -1;

  cout << ans << '\\n';
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}
using P = pair<int, int>;

const int INF = 1e9;
const int N = 1010;

char board[N][N];
int dp[N][N];
int warp[N][N];

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

int h, w;

bool isSafe(int x, int y) {
  if (1 <= x && x <= h && 1 <= y && y <= w && board[x][y] == '.') {
    return true;
  } else {
    return false;
  }
}

signed main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);

  cin >> h >> w;

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

  for (int i = 1; i <= h; i++) {
    for (int j = 1; j <= w; j++) {
      cin >> board[i][j];
    }
  }

  rep(i, N) rep(j, N) dp[i][j] = INF;
  rep(i, N) rep(j, N) warp[i][j] = INF;

  queue<P> que;
  que.emplace(ch, cw);

  // dp 歩いてきたときのワープ回数
  // warp そこまでワープしてきた時のワープ回数
  dp[ch][cw] = 0;
  warp[ch][cw] = 0;

  while (!que.empty()) {
    P p = que.front();
    que.pop();
    int curx = p.first;
    int cury = p.second;

    for (int i = 0; i < 4; i++) {
      int nx = curx + dx[i];
      int ny = cury + dy[i];

      if (!isSafe(nx, ny) ||
          (dp[nx][ny] <= dp[curx][cury] && dp[nx][ny] <= warp[curx][cury]))
        continue;
      que.emplace(nx, ny);
      chmin(dp[nx][ny], dp[curx][cury]);
      chmin(dp[nx][ny], warp[curx][cury]);
    }

    for (int i = -2; i <= 2; i++) {
      for (int j = -2; j <= 2; j++) {
        int nx = curx + i;
        int ny = cury + j;

        if (!isSafe(nx, ny) || (warp[nx][ny] <= warp[curx][cury] + 1 &&
                                warp[nx][ny] <= dp[curx][cury] + 1))
          continue;
        que.emplace(nx, ny);
        chmin(warp[nx][ny], warp[curx][cury] + 1);
        chmin(warp[nx][ny], dp[curx][cury] + 1);
      }
    }
  }

  int ans = min(dp[dh][dw], warp[dh][dw]);
  if (ans >= INF)
    ans = -1;

  cout << ans << '\\n';
}