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

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

typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
static const double EPS = 1e-12;
static const double PI = acos(-1.0);

#define FOR(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define REP(i, n) for (int i = 0; i < (int)(n); i++)
#define ALL(a) (a).begin(), (a).end()
#ifdef LOCAL
#define dbg(x) cerr << __LINE__ << " : " << #x << " = " << (x) << endl
#else
#define dbg(x) true
#endif

const int MAX_N = 1000001;

namespace uf {
int par[MAX_N];
int rank[MAX_N];
int count[MAX_N];
} // namespace uf

void init(int n) {
  for (int i = 0; i < n; i++) {
    uf::par[i] = i;
    uf::rank[i] = 0;
    uf::count[i] = 1;
  }
}

int find(int x) {
  if (uf::par[x] == x) {
    return x;
  } else {
    return uf::par[x] = find(uf::par[x]);
  }
}

void unite(int x, int y) {
  x = find(x);
  y = find(y);
  if (x == y)
    return;

  if (uf::rank[x] < uf::rank[y]) {
    uf::par[x] = y;
    uf::count[y] += uf::count[x];
  } else {
    uf::par[y] = x;
    if (uf::rank[x] == uf::rank[y])
      uf::rank[x]++;
    uf::count[x] += uf::count[y];
  }
}

int group_size(int x) { return uf::count[find(x)]; }

bool same(int x, int y) { return find(x) == find(y); }

const int MAX_V = 1000001; // TODO
const ll INF = INT_MAX;

struct Edge {
  int to;
  ll cost;
};
typedef pair<ll, int> P; // firstは最短距離、secondは頂点の番号

int V = 1000001;       // 頂点数 TODO
vector<Edge> G[MAX_V]; // グラフ TODO
ll d[MAX_V];           // 頂点sからの最短距離
int prev_[MAX_V];      // 最短路の直前の頂点

void dijkstra(int s) {
  priority_queue<P, vector<P>, greater<P>> que;
  fill(d, d + V, INF);
  fill(prev_, prev_ + V, -1);
  d[s] = 0;
  que.push(P(0, s));

  while (!que.empty()) {
    P p = que.top();
    que.pop();
    int v = p.second;
    if (d[v] < p.first)
      continue;
    for (int i = 0; i < (int)G[v].size(); i++) {
      Edge e = G[v][i];
      if (d[e.to] > d[v] + e.cost) {
        d[e.to] = d[v] + e.cost;
        prev_[e.to] = v;
        que.push(P(d[e.to], e.to));
      }
    }
  }
}

vector<int> get_path(int t) {
  vector<int> path;

  for (; t != -1; t = prev_[t]) {
    path.push_back(t);
  }
  reverse(path.begin(), path.end());
  return path;
}

int main() {
  ll H, W;
  cin >> H >> W;
  init(W * H);
  ll Ch, Cw;
  cin >> Ch >> Cw;
  Ch--;
  Cw--;
  ll Dh, Dw;
  cin >> Dh >> Dw;
  Dh--;
  Dw--;
  vector<string> s(H);
  REP(i, H) { cin >> s[i]; }
  vector<pair<ll, ll>> dv = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
  REP(y, H) {
    REP(x, W) {
      if (s[y][x] == '.') {
        REP(i, dv.size()) {
          ll dx = dv[i].first;
          ll dy = dv[i].second;
          if (0 <= x + dx && x + dx < W && 0 <= y + dy && y + dy < H) {
            if (s[y + dy][x + dx] == '.') {
              unite(y * W + x, (y + dy) * W + (x + dx));
            }
          }
        }
      }
    }
  }
  REP(y, H) {
    REP(x, W) {
      if (s[y][x] == '.') {
        for (ll dy = -2; dy <= 2; dy++) {
          for (ll dx = -2; dx <= 2; dx++) {
            if (0 <= x + dx && x + dx < W && 0 <= y + dy && y + dy < H) {
              if (s[y + dy][x + dx] == '.') {
                if (!same(y * W + x, (y + dy) * W + (x + dx))) {
                  G[find(y * W + x)].push_back(
                      {find((y + dy) * W + (x + dx)), 1});
                  G[find((y + dy) * W + (x + dx))].push_back(
                      {find(y * W + x), 1});
                }
              }
            }
          }
        }
      }
    }
  }
  dijkstra(find(Ch * W + Cw));
  if (d[find(Dh * W + Dw)] == INF) {
    cout << -1 << endl;

  } else {
    cout << d[find(Dh * W + Dw)] << endl;
  }
  return 0;
}


Error: TLE

Fixed submission:

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

typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
static const double EPS = 1e-12;
static const double PI = acos(-1.0);

template <class T> using V = vector<T>;
template <class T> using VV = V<V<T>>;

#define FOR(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define REP(i, n) for (int i = 0; i < (int)(n); i++)
#define ALL(a) (a).begin(), (a).end()
#ifdef LOCAL
#define dbg(x) cerr << __LINE__ << " : " << #x << " = " << (x) << endl
#else
#define dbg(x) true
#endif

struct State {
  ll x;
  ll y;
};

int main() {
  ll H, W;
  cin >> H >> W;
  ll Ch, Cw;
  cin >> Ch >> Cw;
  Ch--;
  Cw--;
  ll Dh, Dw;
  cin >> Dh >> Dw;
  Dh--;
  Dw--;
  V<string> s(H);
  REP(i, H) { cin >> s[i]; }
  V<V<bool>> done(H, V<bool>(W, false));
  V<pair<ll, ll>> d = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
  queue<State> q;
  q.push({Cw, Ch});
  done[Ch][Cw] = true;
  ll n = 0;
  while (true) {
    while (!q.empty()) {
      auto v = q.front();
      q.pop();
      ll x = v.x;
      ll y = v.y;
      if (x == Dw && y == Dh) {
        cout << n << endl;
        return 0;
      }
      REP(i, d.size()) {
        ll dx = d[i].first;
        ll dy = d[i].second;
        if (0 <= x + dx && x + dx < W && 0 <= y + dy && y + dy < H) {
          if (s[y + dy][x + dx] == '.' && !done[y + dy][x + dx]) {
            q.push({x + dx, y + dy});
            done[y + dy][x + dx] = true;
          }
        }
      }
    }
    n++;
    V<V<bool>> done2(H, V<bool>(W, false));
    REP(y, H) {
      REP(x, W) {
        if (done[y][x]) {
          for (ll dy = -2; dy <= 2; dy++) {
            for (ll dx = -2; dx <= 2; dx++) {
              if (0 <= x + dx && x + dx < W && 0 <= y + dy && y + dy < H) {
                if (s[y + dy][x + dx] == '.' && !done[y + dy][x + dx]) {
                  q.push({x + dx, y + dy});
                  done2[y + dy][x + dx] = true;
                }
              }
            }
          }
        }
      }
    }
    if (q.empty()) {
      break;
    }
    REP(y, H) {
      REP(x, W) {
        if (done2[y][x]) {
          done[y][x] = true;
        }
      }
    }
  }
  cout << -1 << endl;
  return 0;
}