Problem p02579 (C++)

Buggy submission (status: Runtime Error):

// Problem : D - Wizard in Maze
// Contest : AtCoder - AtCoder Beginner Contest 176
// URL : https://atcoder.jp/contests/abc176/tasks/abc176_d
// Memory Limit : 1024 MB
// Time Limit : 2000 ms
// Powered by CP Editor (https://github.com/cpeditor/cpeditor)

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp> // Common file
#include <ext/pb_ds/tree_policy.hpp> // Including tree_order_statistics_node_update

using namespace std;
using namespace __gnu_pbds;

typedef tree<int, null_type, less<int>, rb_tree_tag,
             tree_order_statistics_node_update>
    ordered_set;

#define FOR(i, a, b) for (int i = (a); i <= (b); ++i)
#define FORD(i, a, b) for (int i = (a); i >= (b); --i)
#define RI(i, n) FOR(i, 1, (n))
#define REP(i, n) FOR(i, 0, (n)-1)
#define mini(a, b) a = min(a, b)
#define maxi(a, b) a = max(a, b)
#define pb push_back
#define st first
#define nd second
#define sz(w) (int)w.size()
typedef vector<int> vi;
typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<pii, int> para;
const ll inf = 1e18 + 7;
const ll maxN = 1e3 + 5;
const ll MOD = 1e9 + 7;

int n, m, x_s, y_s, x2, y2;
int blocked[maxN][maxN];
int color[maxN][maxN];
bool used[maxN][maxN];
int dist[maxN * maxN];
set<int> graph[maxN];

vector<pii> neigh = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};

void BFS_cell(int i, int j, int col) {
  queue<pii> Q;
  Q.push({i, j});
  while (!Q.empty()) {
    pii u = Q.front();
    Q.pop();
    // if (used[u.st][u.nd]) continue;
    // cout << u.st << " " << u.nd << endl;
    used[u.st][u.nd] = true;
    color[u.st][u.nd] = col;
    for (auto nn : neigh) {
      int xx = u.st + nn.st;
      int yy = u.nd + nn.nd;
      // cout << "neigh " << xx << " " << yy << endl;
      if (xx < 0 || xx >= n || yy < 0 || yy >= m)
        continue;
      if (!used[xx][yy] && !blocked[xx][yy]) {
        used[xx][yy] = true;
        Q.push({xx, yy});
      }
    }
  }
  // cout << endl;
}

// sprawdz MODULO!
int main() {
  mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  cin >> n >> m;
  cin >> x_s >> y_s;
  cin >> x2 >> y2;
  REP(i, n) {
    string s;
    cin >> s;
    REP(j, m) {
      if (s[j] == '#')
        blocked[i][j] = true;
      else
        blocked[i][j] = false;
    }
  }
  int col = 1;
  REP(i, n) {
    REP(j, m) {
      if (!used[i][j] && !blocked[i][j]) {
        BFS_cell(i, j, col++);
      }
    }
  }
  REP(i, n) {
    REP(j, m) {
      if (color[i][j] == 0)
        continue;
      FOR(k, -2, 2) {
        FOR(l, -2, 2) {
          int xx = i + k;
          int yy = j + l;
          if (xx < 0 || xx >= n || yy < 0 || yy >= m)
            continue;
          if (color[xx][yy] != color[i][j] && color[xx][yy] != 0) {
            graph[color[i][j]].insert(color[xx][yy]);
            graph[color[xx][yy]].insert(color[i][j]);
          }
        }
      }
    }
  }
  REP(i, 1e6 + 1) { dist[i] = -1; }
  int start = color[x_s - 1][y_s - 1];
  dist[start] = 0;
  queue<int> Q;
  Q.push(start);
  while (!Q.empty()) {
    int u = Q.front();
    Q.pop();
    // cout << u << endl;
    if (u == color[x2 - 1][y2 - 1])
      break;
    for (auto x : graph[u]) {
      // cout << "edge " << x << endl;
      if (dist[x] == -1) {
        dist[x] = dist[u] + 1;
        Q.push(x);
      }
    }
  }
  cout << dist[color[x2 - 1][y2 - 1]];
  return 0;
}


Fixed submission:

// Problem : D - Wizard in Maze
// Contest : AtCoder - AtCoder Beginner Contest 176
// URL : https://atcoder.jp/contests/abc176/tasks/abc176_d
// Memory Limit : 1024 MB
// Time Limit : 2000 ms
// Powered by CP Editor (https://github.com/cpeditor/cpeditor)

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp> // Common file
#include <ext/pb_ds/tree_policy.hpp> // Including tree_order_statistics_node_update

using namespace std;
using namespace __gnu_pbds;

typedef tree<int, null_type, less<int>, rb_tree_tag,
             tree_order_statistics_node_update>
    ordered_set;

#define FOR(i, a, b) for (int i = (a); i <= (b); ++i)
#define FORD(i, a, b) for (int i = (a); i >= (b); --i)
#define RI(i, n) FOR(i, 1, (n))
#define REP(i, n) FOR(i, 0, (n)-1)
#define mini(a, b) a = min(a, b)
#define maxi(a, b) a = max(a, b)
#define pb push_back
#define st first
#define nd second
#define sz(w) (int)w.size()
typedef vector<int> vi;
typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<pii, int> para;
const ll inf = 1e18 + 7;
const ll maxN = 1e3 + 5;
const ll MOD = 1e9 + 7;

int n, m, x_s, y_s, x2, y2;
int blocked[maxN][maxN];
int color[maxN][maxN];
bool used[maxN][maxN];
int dist[maxN * maxN];
set<int> graph[maxN * maxN];

vector<pii> neigh = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};

void BFS_cell(int i, int j, int col) {
  queue<pii> Q;
  Q.push({i, j});
  while (!Q.empty()) {
    pii u = Q.front();
    Q.pop();
    // if (used[u.st][u.nd]) continue;
    // cout << u.st << " " << u.nd << endl;
    used[u.st][u.nd] = true;
    color[u.st][u.nd] = col;
    for (auto nn : neigh) {
      int xx = u.st + nn.st;
      int yy = u.nd + nn.nd;
      // cout << "neigh " << xx << " " << yy << endl;
      if (xx < 0 || xx >= n || yy < 0 || yy >= m)
        continue;
      if (!used[xx][yy] && !blocked[xx][yy]) {
        used[xx][yy] = true;
        Q.push({xx, yy});
      }
    }
  }
  // cout << endl;
}

// sprawdz MODULO!
int main() {
  mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  cin >> n >> m;
  cin >> x_s >> y_s;
  cin >> x2 >> y2;
  REP(i, n) {
    string s;
    cin >> s;
    REP(j, m) {
      if (s[j] == '#')
        blocked[i][j] = true;
      else
        blocked[i][j] = false;
    }
  }
  int col = 1;
  REP(i, n) {
    REP(j, m) {
      if (!used[i][j] && !blocked[i][j]) {
        BFS_cell(i, j, col++);
      }
    }
  }
  REP(i, n) {
    REP(j, m) {
      if (color[i][j] == 0)
        continue;
      FOR(k, -2, 2) {
        FOR(l, -2, 2) {
          int xx = i + k;
          int yy = j + l;
          if (xx < 0 || xx >= n || yy < 0 || yy >= m)
            continue;
          if (color[xx][yy] != color[i][j] && color[xx][yy] != 0) {
            graph[color[i][j]].insert(color[xx][yy]);
            graph[color[xx][yy]].insert(color[i][j]);
          }
        }
      }
    }
  }
  REP(i, 1e6 + 1) { dist[i] = -1; }
  int start = color[x_s - 1][y_s - 1];
  dist[start] = 0;
  queue<int> Q;
  Q.push(start);
  while (!Q.empty()) {
    int u = Q.front();
    Q.pop();
    // cout << u << endl;
    if (u == color[x2 - 1][y2 - 1])
      break;
    for (auto x : graph[u]) {
      // cout << "edge " << x << endl;
      if (dist[x] == -1) {
        dist[x] = dist[u] + 1;
        Q.push(x);
      }
    }
  }
  cout << dist[color[x2 - 1][y2 - 1]];
  return 0;
}