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

#include <bits/stdc++.h>

using namespace std;

const long long INF = 2e9 + 3;
const int N = 1e3 + 3;
const int MOD = 1e9 + 7;
const double EPS = 1e-9;

const double PI = acos(-1);

int n, m;
char a[N][N];
pair<int, int> st, en;
vector<char> used(N *N, 0);
set<int> gr[N * N];
int dd[4][2] = {{0, -1}, {-1, 0}, {0, 1}, {1, 0}};

auto h = [](pair<int, int> x) { return x.first * 1000 + x.second; };
auto p = [](int x) { return make_pair(x / 1000, x % 1000); };
auto valid = [](pair<int, int> x) {
  return x.first >= 0 && x.first < n && x.second >= 0 && x.second < m &&
         a[x.first][x.second] != '#';
};

int par[N * N], rnk[N * N];

int find(int v) {
  if (v == par[v])
    return v;
  return par[v] = find(par[v]);
}

void unite(int x, int y) {
  x = find(x), y = find(y);
  if (x != y) {
    if (rnk[x] < rnk[y])
      swap(x, y);
    par[y] = x;
    rnk[x] == rnk[y] ? rnk[x]++ : 1;
  }
}

void join(int cur) {
  used[cur] = 1;
  for (int k = 0; k < 4; k++) {
    auto to = make_pair(p(cur).first + dd[k][0], p(cur).second + dd[k][1]);
    if (valid(to) && !used[h(to)]) {
      unite(cur, h(to));
      join(h(to));
    }
  }
}

void bfs(int start) {
  queue<pair<int, int>> q;
  q.push({start, 0});
  used[start] = 1;
  while (!q.empty()) {
    int cur = q.front().first, lng = q.front().second;
    q.pop();
    if (cur == find(h(en))) {
      cout << lng;
      exit(0);
    }
    for (int to : gr[cur]) {
      if (!used[to]) {
        used[to] = 1;
        q.push({to, lng + 1});
      }
    }
  }
}

void solve() {
  cin >> n >> m >> st.first >> st.second >> en.first >> en.second;
  st.first--, st.second--, en.first--, en.second--;
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      cin >> a[i][j];
      if (a[i][j] == '.')
        par[h({i, j})] = h({i, j});
    }
  }
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      if (valid({i, j}) && !used[h({i, j})]) {
        join(h({i, j}));
      }
    }
  }
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      if (a[i][j] == '#')
        continue;
      for (int dx = -2; dx <= 2; dx++) {
        for (int dy = -2; dy <= 2; dy++) {
          auto to = make_pair(i + dx, j + dy);
          if (!valid(to))
            continue;
          int u = h({i, j}), v = h(to);
          int l1 = find(u), l2 = find(v);
          if (l1 != l2) {
            gr[l1].insert(l2);
            gr[l2].insert(l1);
          }
        }
      }
    }
  }
  used.assign(N * N, 0);
  bfs(find(h(st)));
  cout << -1;
}

int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0), cout.tie(0);
  int t;
  t = 1;
  while (t--) {
    solve();
  }
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>

using namespace std;

const int INF = 2e9 + 3;
const int N = 1e3 + 3;
const int MOD = 1e9 + 7;
const double EPS = 1e-9;

const double PI = acos(-1);

int n, m;
char a[N][N];
int sr, sc, er, ec;
int dd[4][2] = {{0, -1}, {-1, 0}, {0, 1}, {1, 0}};
int dg[4][2] = {{-1, -1}, {-1, 1}, {1, 1}, {1, -1}};
int dr[16][2] = {{-2, 2}, {-2, 1}, {-2, 0}, {-2, -1}, {-2, -2}, {-1, -2},
                 {0, -2}, {1, -2}, {2, -2}, {2, -1},  {2, 0},   {2, 1},
                 {2, 2},  {1, 2},  {0, 2},  {-1, 2}};
int dp[N][N];
int ans;

bool valid(int r, int c) { return r >= 1 && r <= n && c >= 1 && c <= m; }

void dfs(int r, int c, int cost) {
  if (r == er && c == ec) {
    ans = min(ans, cost);
    return;
  }
  dp[r][c] = min(dp[r][c], cost);
  for (int k = 0; k < 4; k++) {
    int rto = r + dd[k][0], cto = c + dd[k][1];
    if (!valid(rto, cto) || a[rto][cto] == '#')
      continue;
    if (cost < dp[rto][cto])
      dfs(rto, cto, cost);
  }
  for (int k = 0; k < 16; k++) {
    int rto = r + dr[k][0], cto = c + dr[k][1];
    if (!valid(rto, cto) || a[rto][cto] == '#')
      continue;
    if (cost + 1 < dp[rto][cto])
      dfs(rto, cto, cost + 1);
  }
  for (int k = 0; k < 4; k++) {
    int rto = r + dg[k][0], cto = c + dg[k][1];
    if (!valid(rto, cto) || a[rto][cto] == '#')
      continue;
    if (cost + 1 < dp[rto][cto])
      dfs(rto, cto, cost + 1);
  }
}

void solve() {
  cin >> n >> m >> sr >> sc >> er >> ec;
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++)
      cin >> a[i][j];
  }
  memset(dp, INF, sizeof(dp));
  ans = INF;
  dfs(sr, sc, 0);
  if (ans == INF)
    ans = -1;
  cout << ans;
}

int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0), cout.tie(0);
  int t;
  t = 1;
  while (t--) {
    solve();
  }
}