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

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <map>
#include <queue>
#include <set>
using namespace std;
typedef long long LL;
const int SIZEN = 1010;
int Sx, Sy, Tx, Ty;
int N, M;
char mp[SIZEN][SIZEN];
int id[SIZEN][SIZEN];
int root[SIZEN * SIZEN];
int f[SIZEN * SIZEN];
int xx[] = {0, 0, 0, -1, 1};
int yy[] = {0, -1, 1, 0, 0};

struct Link {
  int to, next;
} link[SIZEN * SIZEN * 50];
int head[SIZEN * SIZEN];
int tot = 0;
void add(int from, int to) {
  link[++tot].to = to;
  link[tot].next = head[from];
  head[from] = tot;
}
int find(int x) {
  if (root[x] == x)
    return root[x];
  return root[x] = find(root[x]);
}
queue<int> q;
void BFS() {
  memset(f, 0x3f, sizeof f);
  f[find(id[Sx][Sy])] = 0;
  q.push(find(id[Sx][Sy]));
  while (!q.empty()) {
    int x = q.front();
    q.pop();
    if (x == find(id[Tx][Ty])) {
      printf("%d\\n", f[x]);
      return;
    }
    for (int i = head[x]; i; i = link[i].next) {
      int p = link[i].to;
      if (f[p] <= f[x] + 1)
        continue;
      f[p] = f[x] + 1;
      q.push(p);
    }
  }
  puts("-1");
}

int main() {
  scanf("%d%d", &N, &M);
  scanf("%d%d%d%d", &Sx, &Sy, &Tx, &Ty);
  for (int i = 1; i <= N; i++) {
    scanf("%s", mp[i] + 1);
  }
  int cnt = 0;
  for (int i = 1; i <= N; i++) {
    for (int j = 1; j <= M; j++)
      id[i][j] = ++cnt;
  }
  for (int i = 1; i <= cnt; i++)
    root[i] = i;
  for (int i = 1; i <= N; i++) {
    for (int j = 1; j <= M; j++) {
      if (mp[i][j] == '#')
        continue;
      for (int k = 1; k <= 4; k++) {
        int x = i + xx[k], y = j + yy[k];
        if (x < 1 || y < 1 || x > N || y > M || mp[x][y] == '#') {
          continue;
        }
        int fa = find(id[x][y]);
        int fb = find(id[i][j]);
        if (fa == fb)
          continue;
        root[fa] = fb;
      }
    }
  }
  for (int i = 1; i <= N; i++) {
    for (int j = 1; j <= M; j++) {
      if (mp[i][j] == '#')
        continue;
      for (int l = -2; l <= 2; l++) {
        for (int r = -2; r <= 2; r++) {
          int x = i + l, y = j + r;
          if (x < 1 || y < 1 || x > N || y > M || mp[x][y] == '#') {
            continue;
          }
          int fa = find(id[x][y]);
          int fb = find(id[i][j]);
          if (fa == fb)
            continue;
          add(fa, fb);
          add(fb, fa);
        }
      }
    }
  }
  BFS();
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <map>
#include <queue>
#include <set>
using namespace std;
typedef long long LL;
const int SIZEN = 1010;
int Sx, Sy, Tx, Ty;
int N, M;
char mp[SIZEN][SIZEN];
struct Node {
  int x, y;
  Node() {}
  Node(int x, int y) {
    this->x = x;
    this->y = y;
  }
};
queue<Node> q;
int f[SIZEN][SIZEN];
int xx[] = {0, 1, -1, 0, 0};
int yy[] = {0, 0, 0, 1, -1};
void BFS() {
  memset(f, 0x3f, sizeof f);
  f[Sx][Sy] = 0;
  q.push(Node(Sx, Sy));
  while (!q.empty()) {
    Node D = q.front();
    q.pop();
    for (int i = 1; i <= 4; i++) {
      int x = D.x + xx[i];
      int y = D.y + yy[i];
      if (x > N || y > M || x < 1 || y < 1 || f[x][y] <= f[D.x][D.y] ||
          mp[x][y] == '#')
        continue;
      f[x][y] = f[D.x][D.y];
      q.push(Node(x, y));
    }
    for (int i = -2; i <= 2; i++) {
      for (int j = -2; j <= 2; j++) {
        int x = D.x + i;
        int y = D.y + j;
        if (x > N || y > M || x < 1 || y < 1 || f[x][y] <= f[D.x][D.y] + 1 ||
            mp[x][y] == '#')
          continue;
        f[x][y] = f[D.x][D.y] + 1;
        q.push(Node(x, y));
      }
    }
  }
  printf("%d\\n", f[Tx][Ty] == 0x3f3f3f3f ? -1 : f[Tx][Ty]);
}
int main() {
  scanf("%d%d", &N, &M);
  scanf("%d%d%d%d", &Sx, &Sy, &Tx, &Ty);
  for (int i = 1; i <= N; i++) {
    scanf("%s", mp[i] + 1);
  }
  BFS();
  return 0;
}