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

#include <bits/stdc++.h>
using namespace std;

const long long INF = 1LL << 60;

bool foot_visited[1010][1010];
bool magic_visited[1010][1010];
bool magictriedfrom[1010][1010];
bool magictriedto[1010][1010];

// bool foot_visited[10][10];
// bool magic_visited[10][10];
long long magic[1010][1010];
// long long magic[10][10];

vector<string> field;

int H, W;

// 四方向への移動ベクトル
const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};

int main() {
  cin >> H >> W;
  int CH, CW;
  cin >> CH >> CW;
  CH--;
  CW--;
  int DH, DW;
  cin >> DH >> DW;
  DH--;
  DW--;

  // init
  for (int i = 0; i < H; ++i) {
    for (int j = 0; j < W; ++j) {
      magic[i][j] = INF;
    }
  }

  field.resize(H);
  for (int h = 0; h < H; ++h)
    cin >> field[h];

  int magic_cnt = 0;

  // BFS
  queue<pair<pair<int, int>, long long>> foot_que;
  queue<pair<pair<int, int>, long long>> magic_que;

  magic[CH][CW] = 0;

  foot_que.push({{CH, CW}, 0});

  while (!foot_que.empty() || !magic_que.empty()) {
    while (!foot_que.empty()) {
      int h = foot_que.front().first.first;
      int w = foot_que.front().first.second;
      long long cnt = foot_que.front().second;
      magic[h][w] = min(magic[h][w], cnt);

      foot_visited[h][w] = true;
      foot_que.pop();
      // 歩く場合
      for (int dir = 0; dir < 4; ++dir) {
        int nh = h + dx[dir];
        int nw = w + dy[dir];

        // 移動先が探索済みの場合
        if (foot_visited[nh][nw])
          continue;

        // 場外アウトしたり、移動先が壁の場合はスルー
        if (nh < 0 || nh >= H || nw < 0 || nw >= W)
          continue;

        if (field[nh][nw] == '#' && magictriedfrom[h][w] == false) {
          magictriedfrom[h][w] = true;
          magic_que.push({{h, w}, cnt});
        }

        if (field[nh][nw] == '#')
          continue;
        foot_que.push({{nh, nw}, cnt});
      }
    }

    while (!magic_que.empty()) {
      int h = magic_que.front().first.first;
      int w = magic_que.front().first.second;
      long long cnt = magic_que.front().second;
      magic[h][w] = min(magic[h][w], cnt);

      magic_visited[h][w] = true;
      magic_que.pop();
      // 魔法の場合
      for (int dx = -2; dx <= 2; ++dx) {
        for (int dy = -2; dy <= 2; ++dy) {
          magic_visited[h][w] = true;
          int mnh = h + dx;
          int mnw = w + dy;
          long long new_cnt = cnt + 1;

          // 場外アウトしたり、移動先が壁の場合はスルー
          if (mnh < 0 || mnh >= H || mnw < 0 || mnw >= W)
            continue;
          if (field[mnh][mnw] == '#')
            continue;

          // 移動先が探索済みの場合
          if (magic_visited[mnh][mnw])
            continue;
          if (foot_visited[mnh][mnw])
            continue;
          if (magictriedto[mnh][mnw])
            continue;
          else
            magictriedto[mnh][mnw] = true;

          foot_que.push({{mnh, mnw}, new_cnt});
        }
      }
    }
  }

  long long ans = magic[DH][DW];
  if (ans == INF) {
    cout << -1 << endl;
  } else {
    cout << ans << endl;
  }
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;

const long long INF = 1LL << 60;

bool foot_visited[1010][1010];
bool magic_visited[1010][1010];
bool magictried[1010][1010];

// bool foot_visited[10][10];
// bool magic_visited[10][10];

long long magic[1010][1010];
// long long magic[10][10];

vector<string> field;

int H, W;

// 四方向への移動ベクトル
const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};

int main() {
  cin >> H >> W;
  int CH, CW;
  cin >> CH >> CW;
  CH--;
  CW--;
  int DH, DW;
  cin >> DH >> DW;
  DH--;
  DW--;

  // init
  for (int i = 0; i < H; ++i) {
    for (int j = 0; j < W; ++j) {
      magic[i][j] = INF;
    }
  }

  field.resize(H);
  for (int h = 0; h < H; ++h)
    cin >> field[h];

  int magic_cnt = 0;

  // BFS
  queue<pair<pair<int, int>, long long>> foot_que;
  queue<pair<pair<int, int>, long long>> magic_que;

  magic[CH][CW] = 0;

  foot_que.push({{CH, CW}, 0});
  //    magic_que.push({{CH, CW}, 0});

  while (!foot_que.empty() || !magic_que.empty()) {
    while (!foot_que.empty()) {
      int h = foot_que.front().first.first;
      int w = foot_que.front().first.second;
      long long cnt = foot_que.front().second;
      magic[h][w] = min(magic[h][w], cnt);

      foot_visited[h][w] = true;
      foot_que.pop();
      // 歩く場合
      for (int dir = 0; dir < 4; ++dir) {
        int nh = h + dx[dir];
        int nw = w + dy[dir];

        // 移動先が探索済みの場合
        if (foot_visited[nh][nw])
          continue;

        // 場外アウトしたり、移動先が壁の場合はスルー
        if (nh < 0 || nh >= H || nw < 0 || nw >= W)
          continue;
        if (field[nh][nw] == '#' && magictried[h][w] == false) {
          magictried[h][w] = true;
          magic_que.push({{h, w}, cnt});
        }

        if (field[nh][nw] == '#')
          continue;
        foot_que.push({{nh, nw}, cnt});
      }
    }

    while (!magic_que.empty()) {
      int h = magic_que.front().first.first;
      int w = magic_que.front().first.second;
      long long cnt = magic_que.front().second;
      magic[h][w] = min(magic[h][w], cnt);

      magic_visited[h][w] = true;
      magic_que.pop();
      // 魔法の場合
      for (int dx = -2; dx <= 2; ++dx) {
        for (int dy = -2; dy <= 2; ++dy) {
          magic_visited[h][w] = true;
          int mnh = h + dx;
          int mnw = w + dy;
          long long new_cnt = cnt + 1;

          // 場外アウトしたり、移動先が壁の場合はスルー
          if (mnh < 0 || mnh >= H || mnw < 0 || mnw >= W)
            continue;
          if (field[mnh][mnw] == '#')
            continue;

          // 移動先が探索済みの場合
          if (magic_visited[mnh][mnw])
            continue;
          if (foot_visited[mnh][mnw])
            continue;
          foot_que.push({{mnh, mnw}, new_cnt});
        }
      }
      //     if( field[mnh][mnw] == '#' ) continue;
      //     que.push({{nh, nw}, cnt});
      // }
    }
  }

  long long ans = magic[DH][DW];
  if (ans == INF) {
    cout << -1 << endl;
  } else {
    cout << ans << endl;
  }
}