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

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

class UnionFind {
  std::vector<size_t> root;
  const size_t maximum_size;

public:
  UnionFind(const size_t N) : maximum_size(N + 5) {
    this->root = std::vector<size_t>(N + 1, this->maximum_size);
  }

  size_t find_root(const size_t A) {
    if (this->root[A] >= this->maximum_size) {
      return A;
    }
    this->root[A] = this->find_root(this->root[A]);
    return this->root[A];
  }

  size_t size(const size_t A) {
    return this->root[this->find_root(A)] - this->maximum_size + 1;
  }

  bool unite(const size_t A, const size_t B) {
    size_t rootA = find_root(A);
    size_t rootB = find_root(B);
    if (rootA == rootB) {
      return false;
    }

    if (this->size(rootA) < this->size(rootB)) {
      std::swap(rootA, rootB);
    }

    this->root[rootA] += this->root[rootB] - this->maximum_size;
    this->root[rootB] = rootA;

    return true;
  }

  bool has_same_root(const size_t A, const size_t B) {
    return this->find_root(A) == this->find_root(B);
  }
};

int main() {
  size_t H, W, Ch, Cw, Dh, Dw;
  cin >> H >> W >> Ch >> Cw >> Dh >> Dw;
  Ch--;
  Cw--;
  Dh--;
  Dw--;

  vector<string> S(H);
  for (string &s : S) {
    cin >> s;
  }

  UnionFind uf(H * W + 5);
  vector<pair<int, int>> diff{make_pair(0, 1), make_pair(1, 0),
                              make_pair(0, -1), make_pair(-1, 0)};
  for (size_t h = 0; h < H; h++) {
    for (size_t w = 0; w < W; w++) {
      if (S[h][w] == '#') {
        continue;
      }
      for (pair<int, int> d : diff) {
        size_t new_h = h + d.first;
        size_t new_w = w + d.second;
        if (new_h >= H) {
          continue;
        }
        if (new_w >= W) {
          continue;
        }
        if (S[new_h][new_w] == '#') {
          continue;
        }
        uf.unite(W * h + w, W * new_h + new_w);
      }
    }
  }

  vector<vector<size_t>> dp(H, vector<size_t>(W, H * W + 5));
  queue<pair<size_t, size_t>> q;
  q.push(make_pair(Ch, Cw));
  dp[Ch][Cw] = 0;
  while (!q.empty()) {
    size_t h = q.front().first;
    size_t w = q.front().second;
    q.pop();
    for (pair<int, int> d : diff) {
      size_t new_h = h + d.first;
      size_t new_w = w + d.second;
      if (new_h >= H) {
        continue;
      }
      if (new_w >= W) {
        continue;
      }
      if (S[new_h][new_w] == '#') {
        continue;
      }
      if (dp[new_h][new_w] > dp[h][w]) {
        dp[new_h][new_w] = dp[h][w];
        q.push(make_pair(new_h, new_w));
      }
    }
    for (int i = -2; i <= 2; i++) {
      for (int j = -2; j <= 2; j++) {
        size_t new_h = h + i;
        size_t new_w = w + j;
        if (new_h >= H) {
          continue;
        }
        if (new_w >= W) {
          continue;
        }
        if (S[new_h][new_w] == '#') {
          continue;
        }
        if (uf.has_same_root(W * h + w, W * new_h + new_w)) {
          if (dp[new_h][new_w] > dp[h][w]) {
            dp[new_h][new_w] = dp[h][w];
            q.push(make_pair(new_h, new_w));
          }
          continue;
        }
        if (dp[new_h][new_w] > dp[h][w] + 1) {
          dp[new_h][new_w] = dp[h][w] + 1;
          q.push(make_pair(new_h, new_w));
        }
      }
    }
  }

  if (dp[Dh][Dw] == H * W + 5) {
    cout << -1 << endl;
  } else {
    cout << dp[Dh][Dw] << endl;
  }
}


Error: TLE

Fixed submission:

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

int main() {
  size_t H, W, Ch, Cw, Dh, Dw;
  cin >> H >> W >> Ch >> Cw >> Dh >> Dw;
  Ch--;
  Cw--;
  Dh--;
  Dw--;

  vector<string> S(H);
  for (string &s : S) {
    cin >> s;
  }

  vector<vector<size_t>> dp(H, vector<size_t>(W, 1000005));
  queue<pair<size_t, size_t>> q;
  q.push(make_pair(Ch, Cw));
  dp[Ch][Cw] = 0;
  vector<pair<int, int>> diff{make_pair(0, 1), make_pair(1, 0),
                              make_pair(0, -1), make_pair(-1, 0)};
  while (!q.empty()) {
    size_t h = q.front().first;
    size_t w = q.front().second;
    q.pop();
    for (pair<int, int> d : diff) {
      size_t new_h = h + d.first;
      size_t new_w = w + d.second;
      if (new_h >= H) {
        continue;
      }
      if (new_w >= W) {
        continue;
      }
      if (S[new_h][new_w] == '#') {
        continue;
      }
      if (dp[new_h][new_w] > dp[h][w]) {
        dp[new_h][new_w] = dp[h][w];
        q.push(make_pair(new_h, new_w));
      }
    }
    for (int i = -2; i <= 2; i++) {
      for (int j = -2; j <= 2; j++) {
        size_t new_h = h + i;
        size_t new_w = w + j;
        if (new_h >= H) {
          continue;
        }
        if (new_w >= W) {
          continue;
        }
        if (S[new_h][new_w] == '#') {
          continue;
        }
        if (dp[new_h][new_w] > dp[h][w] + 1) {
          dp[new_h][new_w] = dp[h][w] + 1;
          q.push(make_pair(new_h, new_w));
        }
      }
    }
  }
  if (dp[Dh][Dw] == 1000005) {
    cout << -1 << endl;
  } else {
    cout << dp[Dh][Dw] << endl;
  }
}