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

#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> P;
vector<pair<int, int>> vt;
// 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];
        // cout<<nx<<" "<<ny<<endl;
        vt.push_back({nx, ny});
        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;
    }
    vt.clear();
    while (que.size() > 0) {
      P p = que.front();
      // cout<<p.first<<" "<<p.second<<endl;
      que.pop();
      walk(H, W, p.first, p.second, maze, time);
      vt.push_back({p.first, p.second});
    }

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

    for (int i = 0; i < vt.size(); i++) {
      int ni = vt[i].first, nj = vt[i].second;
      warp(H, W, ni, nj, maze, time, que);
    }
    time_max++;
  }

  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<pair<int, int>> vt;
  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を別のものにコピーする

    vt.clear();
    for (int i = 1; i <= H; i++) {
      for (int j = 1; j <= W; j++) {
        if (time[i][j] == time_max) {
          vt.push_back({i, j});
          // warp(H, W, i, j, maze, time, que);
        }
      }
    }
    for (int i = 0; i < vt.size(); i++) {
      int ni = vt[i].first, nj = vt[i].second;
      warp(H, W, ni, nj, maze, time, que);
    }
    time_max++;
  }

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