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

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using P = pair<int, int>;
const long long INF = 1001001001;
const long long MOD = 1000000007;
const double EPS = 1e-10;

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

int h, w, sy, sx, gy, gx;
int grid[1010][1010];
string s[1010];

void bfs(int n, int y, int x) {
  queue<P> que;
  grid[y][x] = n;
  que.push(P(y, x));
  while (!que.empty()) {
    P t = que.front();
    que.pop();
    int cy = t.first, cx = t.second;
    for (int i = 0; i < 4; i++) {
      int ny = cy + dy[i], nx = cx + dx[i];
      if (0 <= ny && ny < h && 0 <= nx && nx < w && s[ny][nx] == '.') {
        if (grid[ny][nx] != -1)
          continue;
        grid[ny][nx] = n;
        que.push(P(ny, nx));
      }
    }
  }
}

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

  cin >> h >> w >> sy >> sx >> gy >> gx;
  sy--, sx--, gy--, gx--;
  for (int i = 0; i < h; i++)
    cin >> s[i];
  for (int i = 0; i < 1010; i++) {
    for (int j = 0; j < 1010; j++) {
      grid[i][j] = -1;
    }
  }
  int n = 0;
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      if (grid[i][j] != -1 || s[i][j] == '#')
        continue;
      bfs(n, i, j);
      n++;
    }
  }
  // 頂点数n
  vector<int> es[n];
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      if (s[i][j] == '#')
        continue;
      for (int ty = -2; ty <= 2; ty++) {
        for (int tx = -2; tx <= 2; tx++) {
          int ny = i + ty, nx = j + tx;
          if (0 <= ny && ny < h && 0 <= nx && nx < w && s[ny][nx] == '.') {
            if (grid[ny][nx] != grid[i][j]) {
              es[grid[i][j]].emplace_back(grid[ny][nx]);
              es[grid[ny][nx]].emplace_back(grid[i][j]);
            }
          }
        }
      }
    }
  }
  int dist[n];
  for (int i = 0; i < n; i++)
    dist[i] = INF;
  dist[grid[sy][sx]] = 0;
  queue<P> que;
  que.push(P(0, grid[sy][sx]));
  while (!que.empty()) {
    P t = que.front();
    que.pop();
    int v = t.second;
    for (auto u : es[v]) {
      if (dist[u] != INF)
        continue;
      if (dist[u] > dist[v] + 1) {
        dist[u] = dist[v] + 1;
        que.push(P(dist[u], u));
      }
    }
  }
  if (dist[grid[gy][gx]] == INF)
    cout << -1 << endl;
  else
    cout << dist[grid[gy][gx]] << endl;
}

/*
各連結成分に整数を割りふる
任意のマスがどの整数を割りふられた連結成分に属するかの判定
連結成分Aに属するマスから連結成分Bに属するマスにワープできるとき、AとBの間に重み1の辺をはる
できたグラフの始点から終点への最短距離を求める
*/

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using P = pair<int, int>;
const long long INF = 1001001001;
const long long MOD = 1000000007;
const double EPS = 1e-10;

using T = tuple<int, int, int>;

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

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

  int h, w, sy, sx, gy, gx;
  cin >> h >> w >> sy >> sx >> gy >> gx;
  sy--, sx--, gy--, gx--;
  string s[h];
  for (int i = 0; i < h; i++)
    cin >> s[i];
  for (int i = 0; i < 1010; i++)
    for (int j = 0; j < 1010; j++) {
      warp[i][j] = INF;
    }
  queue<T> que;
  que.push(T(0, sy, sx));
  while (!que.empty()) {
    T t = que.front();
    que.pop();
    int cnt = get<0>(t);
    int cy = get<1>(t), cx = get<2>(t);
    for (int i = 0; i < 4; i++) {
      int ny = cy + dy[i], nx = cx + dx[i];
      if (0 <= ny && ny < h && 0 <= nx && nx < w && s[ny][nx] == '.') {
        if (warp[ny][nx] > cnt) {
          warp[ny][nx] = cnt;
          que.push(T(cnt, ny, nx));
        }
      }
    }
    for (int ty = -2; ty <= 2; ty++) {
      for (int tx = -2; tx <= 2; tx++) {
        int ny = cy + ty, nx = cx + tx;
        if (0 <= ny && ny < h && 0 <= nx && nx < w && s[ny][nx] == '.') {
          if (warp[ny][nx] > cnt + 1) {
            warp[ny][nx] = cnt + 1;
            que.push(T(cnt + 1, ny, nx));
          }
        }
      }
    }
  }
  if (warp[gy][gx] != INF)
    cout << warp[gy][gx] << endl;
  else
    cout << -1 << endl;
}