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

#include <bits/stdc++.h>

#define F first
#define S second
#define MP make_pair
#define pb push_back
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()
#define LCM(a, b) (a) / __gcd((a), (b)) * (b)
#define CEIL(a, b) (a) / (b) + (((a) % (b)) ? 1 : 0)
#define log_2(a) (log((a)) / log(2))
#define ln '\\n'

using namespace std;
using LL = long long;
using ldouble = long double;
using P = pair<int, int>;
using LP = pair<LL, LL>;

static const int INF = INT_MAX;
static const LL LINF = LLONG_MAX;
static const int MIN = INT_MIN;
static const LL LMIN = LLONG_MIN;
static const int MOD = 1e9 + 7;
static const int SIZE = 2000005;

const int dx[] = {0, -1, 1, 0};
const int dy[] = {-1, 0, 0, 1};

vector<LL> Div(LL n) {
  vector<LL> ret;
  for (LL i = 1; i * i <= n; ++i) {
    if (n % i == 0) {
      ret.pb(i);
      if (i * i != n)
        ret.pb(n / i);
    }
  }
  sort(all(ret));
  return ret;
}

int root[SIZE];
void init() {
  for (int i = 0; i < SIZE; ++i) {
    root[i] = i;
  }
}

int Root(int x) {
  if (x == root[x])
    return x;
  return root[x] = Root(root[x]);
}

bool Unite(int x, int y) {
  int rx, ry;
  rx = Root(x);
  ry = Root(y);

  if (rx == ry)
    return false;
  if (rx < ry) {
    root[ry] = rx;

  } else {
    root[rx] = ry;
  }
  return true;
}

int bfs();

int H, W;
P s, g;
int mp[1005][1005];

vector<P> graph[SIZE];

int T(int h, int w) { return h * W + w; }

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

  cin >> H >> W;
  cin >> s.F >> s.S;
  cin >> g.F >> g.S;

  --s.F;
  --s.S;
  --g.F;
  --g.S;

  init();
  for (int i = 0; i < H; ++i) {
    for (int j = 0; j < W; ++j) {
      char c;
      cin >> c;
      if (c == '#')
        mp[i][j] = 1;
    }
  }

  for (int i = 0; i < H; ++i) {
    for (int j = 0; j < W; ++j) {
      if (mp[i][j] == 1)
        continue;
      int n = T(i, j);
      int u = T(i - 1, j);
      int l = T(i, j - 1);
      int r = T(i, j + 1);
      int d = T(i + 1, j);
      if (i - 1 >= 0 && mp[i - 1][j] == 0 && Root(n) != Root(u)) {
        Unite(n, u);
        graph[n].pb(MP(u, 0));
        graph[u].pb(MP(n, 0));
      }
      if (j - 1 >= 0 && mp[i][j - 1] == 0 && Root(n) != Root(l)) {
        Unite(n, l);
        graph[n].pb(MP(l, 0));
        graph[l].pb(MP(n, 0));
      }
      if (j + 1 < W && mp[i][j + 1] == 0 && Root(n) != Root(r)) {
        Unite(n, r);
        graph[n].pb(MP(r, 0));
        graph[r].pb(MP(n, 0));
      }
      if (i + 1 < H && mp[i + 1][j] == 0 && Root(n) != Root(d)) {
        Unite(n, d);
        graph[n].pb(MP(d, 0));
        graph[d].pb(MP(n, 0));
      }
    }
  }

  for (int i = 0; i < H; ++i) {
    for (int j = 0; j < W; ++j) {
      if (mp[i][j] == 1)
        continue;
      for (int k = max(i - 2, 0); k <= min(i + 2, H - 1); ++k) {
        for (int l = max(j - 2, 0); l <= min(j + 2, W - 1); ++l) {
          if (mp[k][l] == 1)
            continue;
          int n = T(i, j);
          int m = T(k, l);
          if (Root(n) != Root(m)) {
            graph[n].pb(MP(m, 1));
            graph[m].pb(MP(n, 1));
          }
        }
      }
    }
  }

  int res = bfs();
  if (res == INF)
    res = -1;
  cout << res << endl;

  return 0;
}

int bfs() {
  deque<P> q;
  q.push_front(MP(T(s.F, s.S), 0));

  int dist[SIZE];
  for (int i = 0; i < SIZE; ++i) {
    dist[i] = INF;
  }

  dist[T(s.F, s.S)] = 0;

  while (!q.empty()) {
    P p = q.front();
    q.pop_front();

    if (dist[p.F] < p.S)
      continue;

    for (P pos : graph[p.F]) {
      if (p.S + pos.S < dist[pos.F]) {
        dist[pos.F] = p.S + pos.S;
        if (pos.S == 0)
          q.push_front(MP(pos.F, dist[pos.F]));
        else
          q.push_back(MP(pos.F, dist[pos.F]));
      }
    }
  }

  return dist[T(g.F, g.S)];
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>

#define F first
#define S second
#define MP make_pair
#define pb push_back
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()
#define LCM(a, b) (a) / __gcd((a), (b)) * (b)
#define CEIL(a, b) (a) / (b) + (((a) % (b)) ? 1 : 0)
#define log_2(a) (log((a)) / log(2))
#define ln '\\n'

using namespace std;
using LL = long long;
using ldouble = long double;
using P = pair<int, int>;
using LP = pair<LL, LL>;

static const int INF = INT_MAX;
static const LL LINF = LLONG_MAX;
static const int MIN = INT_MIN;
static const LL LMIN = LLONG_MIN;
static const int MOD = 1e9 + 7;
static const int SIZE = 2000005;

const int dx[] = {0, -1, 1, 0};
const int dy[] = {-1, 0, 0, 1};

vector<LL> Div(LL n) {
  vector<LL> ret;
  for (LL i = 1; i * i <= n; ++i) {
    if (n % i == 0) {
      ret.pb(i);
      if (i * i != n)
        ret.pb(n / i);
    }
  }
  sort(all(ret));
  return ret;
}

int root[SIZE];
void init() {
  for (int i = 0; i < SIZE; ++i) {
    root[i] = i;
  }
}

int Root(int x) {
  if (x == root[x])
    return x;
  return root[x] = Root(root[x]);
}

bool Unite(int x, int y) {
  int rx, ry;
  rx = Root(x);
  ry = Root(y);

  if (rx == ry)
    return false;
  if (rx < ry) {
    root[ry] = rx;

  } else {
    root[rx] = ry;
  }
  return true;
}

int bfs();

int H, W;
P s, g;
int mp[1005][1005];

vector<P> graph[SIZE];

int T(int h, int w) { return h * W + w; }

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

  cin >> H >> W;
  cin >> s.F >> s.S;
  cin >> g.F >> g.S;

  --s.F;
  --s.S;
  --g.F;
  --g.S;

  init();
  for (int i = 0; i < H; ++i) {
    for (int j = 0; j < W; ++j) {
      char c;
      cin >> c;
      if (c == '#')
        mp[i][j] = 1;
    }
  }

  for (int i = 0; i < H; ++i) {
    for (int j = 0; j < W; ++j) {
      if (mp[i][j] == 1)
        continue;
      int n = T(i, j);
      int u = T(i - 1, j);
      int l = T(i, j - 1);
      int r = T(i, j + 1);
      int d = T(i + 1, j);
      if (i - 1 >= 0 && mp[i - 1][j] == 0 && Root(n) != Root(u)) {
        Unite(n, u);
        graph[n].pb(MP(u, 0));
        graph[u].pb(MP(n, 0));
      }
      if (j - 1 >= 0 && mp[i][j - 1] == 0 && Root(n) != Root(l)) {
        Unite(n, l);
        graph[n].pb(MP(l, 0));
        graph[l].pb(MP(n, 0));
      }
      if (j + 1 < W && mp[i][j + 1] == 0 && Root(n) != Root(r)) {
        Unite(n, r);
        graph[n].pb(MP(r, 0));
        graph[r].pb(MP(n, 0));
      }
      if (i + 1 < H && mp[i + 1][j] == 0 && Root(n) != Root(d)) {
        Unite(n, d);
        graph[n].pb(MP(d, 0));
        graph[d].pb(MP(n, 0));
      }
    }
  }

  for (int i = 0; i < H; ++i) {
    for (int j = 0; j < W; ++j) {
      if (mp[i][j] == 1)
        continue;
      for (int k = max(i - 2, 0); k <= min(i + 2, H - 1); ++k) {
        for (int l = max(j - 2, 0); l <= min(j + 2, W - 1); ++l) {
          if (mp[k][l] == 1)
            continue;
          int n = T(i, j);
          int m = T(k, l);
          if (Root(n) != Root(m)) {
            graph[n].pb(MP(m, 1));
            graph[m].pb(MP(n, 1));
          }
        }
      }
    }
  }

  int res = bfs();
  if (res == INF)
    res = -1;
  cout << res << endl;

  return 0;
}

int bfs() {
  queue<P> q;
  q.push(MP(T(s.F, s.S), 0));

  int dist[SIZE];
  for (int i = 0; i < SIZE; ++i) {
    dist[i] = INF;
  }

  dist[T(s.F, s.S)] = 0;

  while (!q.empty()) {
    P p = q.front();
    q.pop();

    if (dist[p.F] < p.S)
      continue;

    for (P pos : graph[p.F]) {
      if (p.S + pos.S < dist[pos.F]) {
        dist[pos.F] = p.S + pos.S;
        q.push(MP(pos.F, dist[pos.F]));
      }
    }
  }

  return dist[T(g.F, g.S)];
}