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

// 8/22 リアルタイム参加
#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (ll i = 0; i < (n); ++i)
using ll = long long;
using P = pair<int, int>;
using Graph = vector<map<int, int>>;

const int dh[4] = {1, 0, -1, 0};
const int dw[4] = {0, 1, 0, -1};

int H, W;
vector<string> field;

Graph G;

// int seen[1010][1010];
int color[1010][1010];
// int warp[1010][1010];

void dfs(int h, int w, int c = 0) {
  color[h][w] = c;

  // 移動A
  for (int dir = 0; dir < 4; dir++) {
    int nh = h + dh[dir];
    int nw = w + dw[dir];

    if (nh < 0 || nh >= H || nw < 0 || nw >= W)
      continue;
    if (field[nh][nw] == '#')
      continue;

    if (color[nh][nw] != -1)
      continue;

    dfs(nh, nw, c);
  }
}

int main() {
  cin >> H >> W;
  int ch, cw, dh, dw;
  cin >> ch >> cw >> dh >> dw;
  ch--;
  cw--;
  dh--;
  dw--;
  field.resize(H);
  rep(i, H) { cin >> field[i]; }

  rep(h, H) rep(w, W) {
    // seen[h][w] = false;
    // warp[h][w] = -1;
    color[h][w] = -1;
  }

  int count = 0;
  rep(h, H) {
    rep(w, W) {
      if (field[h][w] == '#')
        continue;

      if (color[h][w] == -1) {
        dfs(h, w, count);
        count++;
      }
    }
  }

  // cout << "カラー" << endl;
  // rep(h, H) {
  //     rep(w, W) {
  //         cout << color[h][w];
  //     }
  //     cout << endl;
  // }

  G.resize(count);

  rep(h, H) {
    rep(w, W) {
      if (field[h][w] == '#')
        continue;

      int now = color[h][w];

      // 移動B
      for (int nh = h - 2; nh <= h + 2; nh++) {
        for (int nw = w - 2; nw <= w + 2; nw++) {
          // printf("h, w, nh, nw = %d, %d, %d, %d\\n", h, w, nh, nw);
          if (nh == h && nw == w)
            continue;

          if (nh < 0 || nh >= H || nw < 0 || nw >= W)
            continue;
          if (field[nh][nw] == '#')
            continue;

          int next = color[nh][nw];

          G[now][next]++;
        }
      }
    }
  }

  // 以下、bfs。
  int sc = color[ch][cw]; // スタート地点のカラー
  int gc = color[dh][dw]; // ゴール地点のカラー

  vector<int> dist(count, -1);
  queue<int> que;
  dist[sc] = 0;
  que.push(sc);

  while (!que.empty()) {
    int v = que.front();
    que.pop();
    for (auto p : G[v]) {
      int nv = p.first;
      if (dist[nv] == -1) {
        dist[nv] = dist[v] + 1;
        que.push(nv);
      }
    }
  }

  if (dist[gc] != -1)
    cout << dist[gc] << endl;
  else
    cout << "-1" << endl;

  return 0;
}


Error: TLE

Fixed submission:

// 8/22 リアルタイム参加
#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (ll i = 0; i < (n); ++i)
using ll = long long;
using P = pair<int, int>;

const int dh[4] = {1, 0, -1, 0};
const int dw[4] = {0, 1, 0, -1};

int H, W;
vector<string> field;

bool seen[1010][1010];
int warp[1010][1010];

void dfs(int h, int w, int warp_count) {
  seen[h][w] = true;
  warp[h][w] = warp_count;

  // 移動A
  for (int dir = 0; dir < 4; dir++) {
    int nh = h + dh[dir];
    int nw = w + dw[dir];

    if (nh < 0 || nh >= H || nw < 0 || nw >= W)
      continue;
    if (field[nh][nw] == '#')
      continue;

    if (seen[nh][nw] && warp[nh][nw] <= warp_count)
      continue;

    dfs(nh, nw, warp_count);
  }

  // 移動B
  for (int nh = h - 2; nh <= h + 2; nh++) {
    for (int nw = w - 2; nw <= w + 2; nw++) {
      // printf("h, w, nh, nw = %d, %d, %d, %d\\n", h, w, nh, nw);
      if (nh == h && nw == w)
        continue;

      if (nh < 0 || nh >= H || nw < 0 || nw >= W)
        continue;
      if (field[nh][nw] == '#')
        continue;

      // 到達済みならcontinue
      if (seen[nh][nw] && warp[nh][nw] <= warp_count + 1)
        continue;

      // printf("h, w, nh, nw = %d, %d, %d, %d\\n", h, w, nh, nw);
      // cout << "here?" << endl;

      dfs(nh, nw, warp_count + 1);
    }
  }
}

int main() {
  cin >> H >> W;
  int ch, cw, dh, dw;
  cin >> ch >> cw >> dh >> dw;
  ch--;
  cw--;
  dh--;
  dw--;
  field.resize(H);
  rep(i, H) { cin >> field[i]; }

  rep(h, H) rep(w, W) {
    seen[h][w] = false;
    warp[h][w] = -1;
  }

  dfs(ch, cw, 0);

  // cout << "ワープ回数" << endl;
  // rep(h, H) {
  //     rep(w, W) {
  //         cout << warp[h][w];
  //     }
  //     cout << endl;
  // }

  if (seen[dh][dw])
    cout << warp[dh][dw] << endl;
  else
    cout << "-1" << endl;

  return 0;
}