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

// #define _DEBUG
#include "bits/stdc++.h"
#define CHOOSE(a) CHOOSE2 a
#define CHOOSE2(a0, a1, a2, a3, a4, x, ...) x
#define debug_1(x1) cout << #x1 << ": " << x1 << endl
#define debug_2(x1, x2)                                                        \\
  cout << #x1 << ": " << x1 << ", " #x2 << ": " << x2 << endl
#define debug_3(x1, x2, x3)                                                    \\
  cout << #x1 << ": " << x1 << ", " #x2 << ": " << x2 << ", " #x3 << ": "      \\
       << x3 << endl
#define debug_4(x1, x2, x3, x4)                                                \\
  cout << #x1 << ": " << x1 << ", " #x2 << ": " << x2 << ", " #x3 << ": "      \\
       << x3 << ", " #x4 << ": " << x4 << endl
#define debug_5(x1, x2, x3, x4, x5)                                            \\
  cout << #x1 << ": " << x1 << ", " #x2 << ": " << x2 << ", " #x3 << ": "      \\
       << x3 << ", " #x4 << ": " << x4 << ", " #x5 << ": " << x5 << endl
#ifdef _DEBUG
#define debug(...)                                                             \\
  CHOOSE((__VA_ARGS__, debug_5, debug_4, debug_3, debug_2, debug_1, ~))        \\
  (__VA_ARGS__)
#else
#define debug(...)
#endif
#define rep(index, num) for (int index = 0; index < (int)num; index++)
#define rep1(index, num) for (int index = 1; index <= (int)num; index++)
#define brep(index, num) for (int index = (int)num - 1; index >= 0; index--)
#define brep1(index, num) for (int index = (int)num; index > 0; index--)
#define scan(argument) cin >> argument
#define prin(argument) cout << argument << endl
#define kaigyo cout << endl
#define eps 1e-7
#define mp(a1, a2) make_pair(a1, a2)
#define ALL(a) (a).begin(), (a).end()
#define rALL(a) (a).rbegin(), (a).rend()
typedef long long ll;
typedef long double ld;
using namespace std;
typedef pair<ll, ll> pll;
typedef pair<int, int> pint;
typedef vector<int> vint;
typedef vector<ll> vll;
typedef vector<pint> vpint;
typedef vector<pll> vpll;
ll INFl = (ll)1e+18 + 1;
int INF = 1e+9 + 1;
struct UnionFind {
  vector<int> par;
  vector<int> sizes;
  UnionFind(int n) : par(n), sizes(n, 1) { rep(i, n) par[i] = i; }
  int root(int x) {
    if (x == par[x])
      return x;
    return par[x] = root(par[x]);
  }
  void unite(int x, int y) {
    x = root(x);
    y = root(y);
    if (x == y)
      return;
    if (sizes[x] < sizes[y])
      swap(x, y);
    par[y] = x;
    sizes[x] += sizes[y];
  }
  bool same(int x, int y) { return root(x) == root(y); }
  int size(int x) { return sizes[root(x)]; }
};
int N;
/*ダイクストラ*/
vpint adj[1000000];
int d[1000000], color[1000000];
void dijkstra(int st) {
  priority_queue<pint> PQ; // 辺の長さのオーバーフローに注意！
  rep(i, N) {
    d[i] = INF;
    color[i] = 0;
  }
  d[st] = 0;
  color[st] = 1;
  PQ.push(mp(0, st));
  while (!PQ.empty()) {
    pint f = PQ.top();
    PQ.pop();
    int u = f.second;
    color[u] = 2;
    if (d[u] < -f.first)
      continue;
    rep(j, adj[u].size()) {
      int v = adj[u][j].first;
      if (color[v] == 2)
        continue;
      if (d[v] > d[u] + adj[u][j].second) {
        d[v] = d[u] + adj[u][j].second;
        PQ.push(mp(-d[v], v));
        color[v] = 1;
      }
    }
  }
}
char S[1005][1005];
int ban[1000001];
map<pint, bool> alre;
int main() {
  int H, W;
  int Ch, Cw, Dh, Dw;

  scan(H >> W >> Ch >> Cw >> Dh >> Dw);
  rep(i, H) { scan(S[i]); }
  Ch--;
  Cw--;
  Dh--;
  Dw--;
  UnionFind uf(H * W);
  rep(i, H) {
    rep(j, W) {
      if (i != H - 1 && S[i][j] == '.' && S[i + 1][j] == '.') {
        uf.unite(i * W + j, (i + 1) * W + j);
      }
      if (j != W - 1 && S[i][j] == '.' && S[i][j + 1] == '.') {
        uf.unite(i * W + j, i * W + j + 1);
      }
    }
  }
  int cnt = 0;
  rep(i, H) {
    rep(j, W) {
      if (S[i][j] == '.' && uf.root(i * W + j) == i * W + j) {
        ban[i * W + j] = cnt;
        cnt++;
      }
    }
  }
  N = cnt;
  rep(i, H) {
    rep(j, W) {
      if (S[i][j] == '.') {
        for (int dh = -2; dh <= 2; dh++) {
          for (int dw = -2; dw <= 2; dw++) {
            if (dh == 0 && dw == 0)
              continue;
            int y = i + dh, x = j + dw;
            if (S[y][x] == '.' && !uf.same(i * W + j, y * W + x)) {
              int r1 = ban[uf.root(i * W + j)];
              int r2 = ban[uf.root(y * W + x)];
              if (alre[{r1, r2}] == 0) {
                alre[{r1, r2}] = 1;
                alre[{r2, r1}] = 1;
                adj[r1].push_back({r2, 1});
                adj[r2].push_back({r1, 1});
              }
            }
          }
        }
      }
    }
  }
  int st = ban[uf.root(Ch * W + Cw)];
  int go = ban[uf.root(Dh * W + Dw)];
  dijkstra(st);
  if (d[go] == INF)
    prin(-1);
  else
    prin(d[go]);
  return 0;
}


Error: TLE

Fixed submission:

// #define _DEBUG
#include "bits/stdc++.h"
#define CHOOSE(a) CHOOSE2 a
#define CHOOSE2(a0, a1, a2, a3, a4, x, ...) x
#define debug_1(x1) cout << #x1 << ": " << x1 << endl
#define debug_2(x1, x2)                                                        \\
  cout << #x1 << ": " << x1 << ", " #x2 << ": " << x2 << endl
#define debug_3(x1, x2, x3)                                                    \\
  cout << #x1 << ": " << x1 << ", " #x2 << ": " << x2 << ", " #x3 << ": "      \\
       << x3 << endl
#define debug_4(x1, x2, x3, x4)                                                \\
  cout << #x1 << ": " << x1 << ", " #x2 << ": " << x2 << ", " #x3 << ": "      \\
       << x3 << ", " #x4 << ": " << x4 << endl
#define debug_5(x1, x2, x3, x4, x5)                                            \\
  cout << #x1 << ": " << x1 << ", " #x2 << ": " << x2 << ", " #x3 << ": "      \\
       << x3 << ", " #x4 << ": " << x4 << ", " #x5 << ": " << x5 << endl
#ifdef _DEBUG
#define debug(...)                                                             \\
  CHOOSE((__VA_ARGS__, debug_5, debug_4, debug_3, debug_2, debug_1, ~))        \\
  (__VA_ARGS__)
#else
#define debug(...)
#endif
#define rep(index, num) for (int index = 0; index < (int)num; index++)
#define rep1(index, num) for (int index = 1; index <= (int)num; index++)
#define brep(index, num) for (int index = (int)num - 1; index >= 0; index--)
#define brep1(index, num) for (int index = (int)num; index > 0; index--)
#define scan(argument) cin >> argument
#define prin(argument) cout << argument << endl
#define kaigyo cout << endl
#define eps 1e-7
#define mp(a1, a2) make_pair(a1, a2)
#define ALL(a) (a).begin(), (a).end()
#define rALL(a) (a).rbegin(), (a).rend()
typedef long long ll;
typedef long double ld;
using namespace std;
typedef pair<ll, ll> pll;
typedef pair<int, int> pint;
typedef vector<int> vint;
typedef vector<ll> vll;
typedef vector<pint> vpint;
typedef vector<pll> vpll;
ll INFl = (ll)1e+18 + 1;
int INF = 1e+9 + 1;
struct UnionFind {
  vector<int> par;
  vector<int> sizes;
  UnionFind(int n) : par(n), sizes(n, 1) { rep(i, n) par[i] = i; }
  int root(int x) {
    if (x == par[x])
      return x;
    return par[x] = root(par[x]);
  }
  void unite(int x, int y) {
    x = root(x);
    y = root(y);
    if (x == y)
      return;
    if (sizes[x] < sizes[y])
      swap(x, y);
    par[y] = x;
    sizes[x] += sizes[y];
  }
  bool same(int x, int y) { return root(x) == root(y); }
  int size(int x) { return sizes[root(x)]; }
};
int dp[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
char S[1005][1005];
int dismin[1005][1005];
int main() {
  int H, W;
  int Ch, Cw, Dh, Dw;

  scan(H >> W >> Ch >> Cw >> Dh >> Dw);
  fill(dismin[0], dismin[1005], INF);
  rep(i, H) { scan(S[i]); }
  Ch--;
  Cw--;
  Dh--;
  Dw--;
  UnionFind uf(H * W);
  rep(i, H) {
    rep(j, W) {
      if (i != H - 1 && S[i][j] == '.' && S[i + 1][j] == '.') {
        uf.unite(i * W + j, (i + 1) * W + j);
      }
      if (j != W - 1 && S[i][j] == '.' && S[i][j + 1] == '.') {
        uf.unite(i * W + j, i * W + j + 1);
      }
    }
  }
  vpint record;
  vint redis;
  record.push_back({Ch, Cw});
  redis.push_back(0);
  dismin[Ch][Cw] = 0;
  rep1(count, INF) {
    if (record.empty())
      break;
    vpint before = record;
    vint bedis = redis;
    record.clear();
    redis.clear();
    rep(i, before.size()) {
      debug(before[i].first + 1, before[i].second + 1, bedis[i]);
      rep(j, 4) {
        pint zahyoto = before[i];
        int y = zahyoto.first + dp[j][1];
        int x = zahyoto.second + dp[j][0];
        int dis = bedis[i];
        if (y < 0 || y >= H || x < 0 || x >= W)
          continue;
        if (S[y][x] == '.' && dis < dismin[y][x]) {
          record.push_back(mp(y, x));
          redis.push_back(dis);
          dismin[y][x] = dis;
        }
      }
      for (int dh = -2; dh <= 2; dh++) {
        for (int dw = -2; dw <= 2; dw++) {
          pint zahyoto = before[i];
          int y = zahyoto.first + dh;
          int x = zahyoto.second + dw;
          int dis = bedis[i];
          if (y < 0 || y >= H || x < 0 || x >= W ||
              uf.same(zahyoto.first * W + zahyoto.second, y * W + x))
            continue;
          if (S[y][x] == '.' && dis + 1 < dismin[y][x]) {
            record.push_back(mp(y, x));
            redis.push_back(dis + 1);
            dismin[y][x] = dis + 1;
          }
        }
      }
    }
  }
  if (dismin[Dh][Dw] == INF)
    prin(-1);
  else
    prin(dismin[Dh][Dw]);
  return 0;
}