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

#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> P;

// H×Wの迷路，(sx, sy)から歩いて移動できる所のワープ回数をqueueで求める
// まだ行ったことのないtimeは-1
// que_warpはwalkで値が更新される座標を保持するqueue
void walk(int H, int W, int sx, int sy, vector<vector<char>> &maze,
          vector<vector<int>> &time, queue<P> &que_warp) {
  vector<int> dx = {-1, 1, 0, 0};
  vector<int> dy = {0, 0, -1, 1};

  queue<P> que;
  que.push(P(sx, sy));

  while (que.size() > 0) {
    P p = que.front();
    que.pop();
    for (int i = 0; i < 4; i++) {
      int nx = p.first + dx[i];
      int ny = p.second + dy[i];
      if (nx > 0 && nx <= H && ny > 0 && ny <= W && maze[nx][ny] == '.' &&
          time[nx][ny] == -1) {
        time[nx][ny] = time[p.first][p.second];
        que.push(P(nx, ny));
        que_warp.push(P(nx, ny));
      }
    }
  }
  return;
}

// (sx, sy)からワープで移動できるところのワープ回数を求める
void warp(int H, int W, int sx, int sy, vector<vector<char>> &maze,
          vector<vector<int>> &time, queue<P> &que_walk) {
  for (int i = -2; i <= 2; i++) {
    for (int j = -2; j <= 2; j++) {
      int nx = sx + i;
      int ny = sy + j;
      if (nx > 0 && nx <= H && ny > 0 && ny <= W && maze[nx][ny] == '.' &&
          time[nx][ny] == -1) {
        time[nx][ny] = time[sx][sy] + 1;
        que_walk.push(P(nx, ny));
      }
    }
  }
  return;
}

int main() {
  int H, W, sx, sy, gx, gy; // sはスタート，gはゴール
  cin >> H >> W >> sx >> sy >> gx >> gy;

  vector<vector<char>> maze(H + 1, vector<char>(W + 1));
  for (int i = 1; i <= H; i++) {
    string s;
    cin >> s;
    for (int j = 1; j <= W; j++) {
      maze[i][j] = s[j - 1];
    }
  }

  vector<vector<int>> time(H + 1, vector<int>(W + 1, -1));

  time[sx][sy] = 0;

  queue<P> que_walk;
  que_walk.push(P(sx, sy));

  queue<P> que_warp; // ワープで始点となる座標を入れるqueue

  /* walk (H, W, sx, sy, maze, time, que_warp);
  while (que_warp.size() > 0) {
      P p =que_warp.front();
      que_warp.pop();
      warp (H, W, p.first, p.second, maze, time, que_walk);
  }
  cout << "que_walk:" << endl;
  while (que_walk.size() > 0) {

      P p = que_walk.front();
      que_walk.pop();
      cout << p.first << " " << p.second << endl;
  }
  cout << "que_warp:" << endl;
  while (que_warp.size() > 0) {
      cout << "que_warp:" << endl;
      P p = que_warp.front();
      que_warp.pop();
      cout << p.first << " " << p.second << endl;
  }
  cout << "time:" << endl;
  for (int i = 1; i <= H; i++) {
      for (int j = 1; j <= W; j++){
          cout << setw(3) << time[i][j];
      }
      cout << endl;
  } */

  while (que_walk.size() > 0) {
    if (time[gx][gy] != -1) {
      break;
    }

    while (que_walk.size() > 0) {
      P p = que_walk.front();
      que_walk.pop();
      que_warp.push(P(p.first, p.second));
      walk(H, W, p.first, p.second, maze, time, que_warp);
    }

    while (que_warp.size() > 0) {
      P p = que_warp.front();
      que_warp.pop();
      warp(H, W, p.first, p.second, maze, time, que_walk);
    }
  }

  /*
  cout << "time:" << endl;
  for (int i = 1; i <= H; i++) {
      for (int j = 1; j <= W; j++){
          cout << setw(3) << time[i][j];
      }
      cout << endl;
  }*/

  cout << time[gx][gy] << endl;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> P;

// H×Wの迷路，(sx, sy)から歩いて移動できる所のワープ回数をqueueで求める
// まだ行ったことのないtimeは-1

void walk(int H, int W, int sx, int sy, vector<vector<char>> &maze,
          vector<vector<int>> &time) {
  vector<int> dx = {-1, 1, 0, 0};
  vector<int> dy = {0, 0, -1, 1};

  queue<P> que;
  que.push(P(sx, sy));

  while (que.size() > 0) {
    P p = que.front();
    que.pop();
    for (int i = 0; i < 4; i++) {
      int nx = p.first + dx[i];
      int ny = p.second + dy[i];
      if (nx > 0 && nx <= H && ny > 0 && ny <= W && maze[nx][ny] == '.' &&
          time[nx][ny] == -1) {
        time[nx][ny] = time[p.first][p.second];
        que.push(P(nx, ny));
      }
    }
  }
  return;
}

// (sx, sy)からワープで移動できるところのワープ回数を求める
void warp(int H, int W, int sx, int sy, vector<vector<char>> &maze,
          vector<vector<int>> &time, queue<P> &que) {
  for (int i = -2; i <= 2; i++) {
    for (int j = -2; j <= 2; j++) {
      int nx = sx + i;
      int ny = sy + j;
      if (nx > 0 && nx <= H && ny > 0 && ny <= W && maze[nx][ny] == '.' &&
          time[nx][ny] == -1) {
        time[nx][ny] = time[sx][sy] + 1;
        que.push(P(nx, ny));
      }
    }
  }
  return;
}

int main() {
  int H, W, sx, sy, gx, gy; // sはスタート，gはゴール
  cin >> H >> W >> sx >> sy >> gx >> gy;

  vector<vector<char>> maze(H + 1, vector<char>(W + 1));
  for (int i = 1; i <= H; i++) {
    string s;
    cin >> s;
    for (int j = 1; j <= W; j++) {
      maze[i][j] = s[j - 1];
    }
  }

  vector<vector<int>> time(H + 1, vector<int>(W + 1, -1));

  time[sx][sy] = 0;

  queue<P> que;
  que.push(P(sx, sy));

  int time_max = 0; // timeに書かれている数の最大値

  while (que.size() > 0) {
    if (time[gx][gy] != -1) {
      break;
    }

    while (que.size() > 0) {
      P p = que.front();
      que.pop();
      walk(H, W, p.first, p.second, maze, time);
    }

    // ワープをする
    // 上の歩きでtimeが更新されたところだけからワープしたいので一度timeを別のものにコピーする
    //  auto time1 = time;

    for (int i = 1; i <= H; i++) {
      for (int j = 1; j <= W; j++) {
        if (time[i][j] == time_max) {
          warp(H, W, i, j, maze, time, que);
        }
      }
    }
    time_max++;
  }

  cout << time[gx][gy] << endl;
}