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

/*** author: yuji9511 ***/
#include <bits/stdc++.h>
using namespace std;
// using int = long long;
using lpair = pair<int, int>;
const int MOD = 1e9 + 7;
const int INF = 1e9;
#define rep(i, m, n) for (int i = (m); i < (n); i++)
#define rrep(i, m, n) for (int i = (m); i >= (n); i--)
#define printa(x, n)                                                           \\
  for (int i = 0; i < n; i++) {                                                \\
    cout << (x[i]) << " \\n"[i == n - 1];                                       \\
  };
void print() {}
template <class H, class... T> void print(H &&h, T &&...t) {
  cout << h << " \\n"[sizeof...(t) == 0];
  print(forward<T>(t)...);
}
struct UnionFind {
private:
  int N;
  vector<int> parent;
  vector<int> num;
  vector<int> diff_weight;

public:
  UnionFind(int n) {
    N = n;
    rep(i, 0, N) parent.push_back(i);
    rep(i, 0, N) num.push_back(1);
    rep(i, 0, N) diff_weight.push_back(0);
  }

  int root(int x) {
    if (x == parent[x]) {
      return x;
    } else {
      int r = root(parent[x]);
      diff_weight[x] += diff_weight[parent[x]];
      return parent[x] = r;
    }
  }

  void unite(int a, int b, int w = 0) {
    w += weight(a);
    w -= weight(b);
    a = root(a);
    b = root(b);
    if (a == b)
      return;
    parent[b] = a;
    int sum = num[a] + num[b];
    num[a] = sum;
    num[b] = sum;
    diff_weight[b] = w;
  }

  bool same(int a, int b) { return root(a) == root(b); }

  int sz(int x) { return num[root(x)]; }

  int weight(int x) {
    root(x);
    return diff_weight[x];
  }

  int diff(int a, int b) { return weight(b) - weight(a); }
};

int dist[1000010] = {};
typedef struct {
  int h;
  int w;
  int d;
} P;
vector<int> tree[1000010];

void solve() {
  int H, W;
  cin >> H >> W;
  int Ch, Dh, Cw, Dw;
  cin >> Ch >> Cw >> Dh >> Dw;
  string S[1010];
  rep(i, 0, H) cin >> S[i];
  Ch--;
  Dh--;
  Cw--;
  Dw--;
  int dh[4] = {0, 0, 1, -1};
  int dw[4] = {1, -1, 0, 0};
  // queue<P> que;
  // que.push({Ch, Cw, 0});

  rep(i, 0, H) {
    rep(j, 0, W) { dist[i * W + j] = INF; }
  }
  UnionFind uf(H * W + 10);

  rep(i, 0, H) {
    rep(j, 0, W) {
      if (S[i][j] == '#')
        continue;
      rep(k, 0, 4) {
        int hh = i + dh[k], ww = j + dw[k];
        if (hh >= 0 && hh < H && ww >= 0 && ww < W && S[hh][ww] == '.') {
          uf.unite(i * W + j, hh * W + ww);
        }
      }
    }
  }
  rep(h, 0, H) {
    rep(w, 0, W) {
      if (S[h][w] == '#')
        continue;
      rep(i, -2, 3) {
        rep(j, -2, 3) {
          if (i == 0 && j == 0)
            continue;
          int hh = h + i, ww = w + j;
          if (hh >= 0 && hh < H && ww >= 0 && ww < W && S[hh][ww] == '.') {
            if (not uf.same(h * W + w, hh * W + ww)) {
              // print(h,w,hh,ww);
              tree[uf.root(h * W + w)].push_back(uf.root(hh * W + ww));
            }
          }
        }
      }
    }
  }
  dist[uf.root(Ch * W + Cw)] = 0;
  queue<int> que;
  que.push(uf.root(Ch * W + Cw));
  while (not que.empty()) {
    int p = que.front();
    que.pop();
    for (auto &e : tree[p]) {
      // print(p,e);
      if (dist[e] == INF) {
        dist[e] = dist[p] + 1;
        que.push(e);
      }
    }
  }
  // rep(i,0,H){
  //     rep(j,0,W){
  //         cout << dist[i*W+j] << " ";
  //     }
  //     cout << endl;
  // }
  if (dist[uf.root(Dh * W + Dw)] == INF) {
    print(-1);
  } else {
    print(dist[uf.root(Dh * W + Dw)]);
  }

  // while(not que.empty()){
  //     P l1 = que.front();
  //     que.pop();
  //     int h = l1.h, w = l1.w;
  //     // print(h,w, dist[h][w], l1.d);
  //     if(dist[h][w] <= l1.d) continue;
  //     // if(dist[h][w] != INF) continue;
  //     dist[h][w] = l1.d;
  //     rep(k,0,4){
  //         int hh = h + dh[k];
  //         int ww = w + dw[k];
  //         if(dist[hh][ww] <= l1.d || S[hh][ww] == '#') continue;
  //         if(hh >= 0 && hh < H && ww >= 0 && ww < W){
  //             que.push({hh, ww, l1.d});
  //         }
  //     }
  //     rep(i,-2,3){
  //         rep(j,-2,3){
  //             if(i == 0 && j == 0) continue;
  //             int hh = h + i;
  //             int ww = w + j;
  //             if(dist[hh][ww] <= l1.d+1 || S[hh][ww] == '#') continue;
  //             if(hh >= 0 && hh < H && ww >= 0 && ww < W){
  //                 que.push({hh, ww, l1.d + 1});
  //             }

  //         }
  //     }
  // }
  // if(dist[Dh][Dw] == INF){
  //     print(-1);
  // }else{
  //     print(dist[Dh][Dw]);
  // }
}

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


Error: TLE

Fixed submission:

/*** author: yuji9511 ***/
#include <bits/stdc++.h>
using namespace std;
// using int = long long;
using lpair = pair<int, int>;
const int MOD = 1e9 + 7;
const int INF = 1e9;
#define rep(i, m, n) for (int i = (m); i < (n); i++)
#define rrep(i, m, n) for (int i = (m); i >= (n); i--)
#define printa(x, n)                                                           \\
  for (int i = 0; i < n; i++) {                                                \\
    cout << (x[i]) << " \\n"[i == n - 1];                                       \\
  };
void print() {}
template <class H, class... T> void print(H &&h, T &&...t) {
  cout << h << " \\n"[sizeof...(t) == 0];
  print(forward<T>(t)...);
}
int dist[1010][1010] = {};
typedef struct {
  int h;
  int w;
  int d;
} P;
void solve() {
  int H, W;
  cin >> H >> W;
  int Ch, Dh, Cw, Dw;
  cin >> Ch >> Cw >> Dh >> Dw;
  string S[1010];
  rep(i, 0, H) cin >> S[i];
  Ch--;
  Dh--;
  Cw--;
  Dw--;
  int dh[4] = {0, 0, 1, -1};
  int dw[4] = {1, -1, 0, 0};
  queue<P> que;
  que.push({Ch, Cw, 0});

  rep(i, 0, H) {
    rep(j, 0, W) { dist[i][j] = INF; }
  }
  while (not que.empty()) {
    P l1 = que.front();
    que.pop();
    int h = l1.h, w = l1.w;
    // print(h,w, dist[h][w], l1.d);
    if (dist[h][w] < l1.d)
      continue;
    // if(dist[h][w] != INF) continue;
    // dist[h][w] = l1.d;
    // rep(k,0,4){
    //     int hh = h + dh[k];
    //     int ww = w + dw[k];
    //     if(hh >= 0 && hh < H && ww >= 0 && ww < W){
    //         if(dist[hh][ww] <= l1.d || S[hh][ww] == '#') continue;
    //         que.push({hh, ww, l1.d});
    //     }
    // }
    rep(i, -2, 3) {
      rep(j, -2, 3) {
        if (i == 0 && j == 0)
          continue;
        if (abs(i) + abs(j) == 1) {
          int hh = h + i;
          int ww = w + j;
          if (hh >= 0 && hh < H && ww >= 0 && ww < W) {
            if (dist[hh][ww] <= l1.d || S[hh][ww] == '#')
              continue;
            dist[hh][ww] = l1.d;
            que.push({hh, ww, l1.d});
          }
        } else {
          int hh = h + i;
          int ww = w + j;
          if (hh >= 0 && hh < H && ww >= 0 && ww < W) {
            if (dist[hh][ww] <= l1.d + 1 || S[hh][ww] == '#')
              continue;
            dist[hh][ww] = l1.d + 1;
            que.push({hh, ww, l1.d + 1});
          }
        }
      }
    }
  }
  if (dist[Dh][Dw] == INF) {
    print(-1);
  } else {
    print(dist[Dh][Dw]);
  }
}

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