Problem p02579 (C++) — buggy submission, verdict: Runtime Error

#include <bits/stdc++.h>
using namespace std;

struct UnionFind {
  vector<int> par; // par[i]:iの親の番号　(例) par[3] = 2 : 3の親が2

  UnionFind(int N) : par(N) { // 最初は全てが根であるとして初期化
    for (int i = 0; i < N; i++)
      par[i] = i;
  }

  int root(int x) { // データxが属する木の根を再帰で得る：root(x) = {xの木の根}
    if (par[x] == x)
      return x;
    return par[x] = root(par[x]);
  }

  void unite(int x, int y) { // xとyの木を併合
    int rx = root(x);        // xの根をrx
    int ry = root(y);        // yの根をry
    if (rx == ry)
      return; // xとyの根が同じ(=同じ木にある)時はそのまま
    par[rx] =
        ry; // xとyの根が同じでない(=同じ木にない)時：xの根rxをyの根ryにつける
  }

  bool same(int x, int y) { // 2つのデータx, yが属する木が同じならtrueを返す
    int rx = root(x);
    int ry = root(y);
    return rx == ry;
  }
};

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

int main() {
  int H, W;
  cin >> H >> W;
  int ch, cw, dh, dw;
  cin >> ch >> cw >> dh >> dw;
  ch--;
  cw--;
  dh--;
  dw--;
  UnionFind u(1e7);
  char s[H][W];
  for (int i = 0; i < H; ++i) {
    for (int j = 0; j < W; ++j) {
      cin >> s[i][j];
    }
  }
  for (int i = 0; i < H; ++i) {
    for (int j = 0; j < W; ++j) {
      for (int k = 0; k < 4; ++k) {
        if (s[i][j] == '.' && s[i + dx[k]][j + dy[k]] == '.' &&
            0 <= i + dx[k] && i + dx[k] < H && 0 <= j + dy[k] &&
            j + dy[k] < W) {
          u.unite(i * W + j, (i + dx[k]) * W + j + dy[k]);
        }
      }
    }
  }
  int d[H][W];
  for (int i = 0; i < H; ++i) {
    for (int j = 0; j < W; ++j) {
      if (s[i][j] == '.') {
        int x = u.root(i * W + j);
        d[i][j] = x;
      }
    }
  }
  vector<vector<int>> g(1e7);
  for (int i = 0; i < H; ++i) {
    for (int j = 0; j < W; ++j) {
      for (int k = -2; k <= 2; ++k) {
        for (int l = -2; l <= 2; ++l) {
          if (0 <= i + k && i + k < H && 0 <= j + l && j + l < W &&
              s[i][j] == '.' && s[i + k][j + l] == '.' &&
              d[i][j] != d[i + k][j + l]) {
            g[d[i][j]].push_back(d[i + k][j + l]);
            g[d[i + k][j + l]].push_back(d[i][j]);
          }
        }
      }
    }
  }
  vector<int> ans(1e7, -1);
  queue<int> q;
  int x = u.root(ch * W + cw), y = u.root(dh * W + dw);
  ans[x] = 0;
  q.push(x);
  while (!q.empty()) {
    int v = q.front();
    q.pop();
    for (int nv : g[v]) {
      if (ans[nv] != -1)
        continue;
      ans[nv] = ans[v] + 1;
      q.push(nv);
    }
  }
  cout << ans[y] << endl;
}


Error: 0

Fixed submission:

#include <bits/stdc++.h>
using namespace std;

struct UnionFind {
  vector<int> par; // par[i]:iの親の番号　(例) par[3] = 2 : 3の親が2

  UnionFind(int N) : par(N) { // 最初は全てが根であるとして初期化
    for (int i = 0; i < N; i++)
      par[i] = i;
  }

  int root(int x) { // データxが属する木の根を再帰で得る：root(x) = {xの木の根}
    if (par[x] == x)
      return x;
    return par[x] = root(par[x]);
  }

  void unite(int x, int y) { // xとyの木を併合
    int rx = root(x);        // xの根をrx
    int ry = root(y);        // yの根をry
    if (rx == ry)
      return; // xとyの根が同じ(=同じ木にある)時はそのまま
    par[rx] =
        ry; // xとyの根が同じでない(=同じ木にない)時：xの根rxをyの根ryにつける
  }

  bool same(int x, int y) { // 2つのデータx, yが属する木が同じならtrueを返す
    int rx = root(x);
    int ry = root(y);
    return rx == ry;
  }
};

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

int main() {
  int H, W;
  cin >> H >> W;
  int ch, cw, dh, dw;
  cin >> ch >> cw >> dh >> dw;
  ch--;
  cw--;
  dh--;
  dw--;
  UnionFind u(H * W);
  char s[H][W];
  for (int i = 0; i < H; ++i) {
    for (int j = 0; j < W; ++j) {
      cin >> s[i][j];
    }
  }
  for (int i = 0; i < H; ++i) {
    for (int j = 0; j < W; ++j) {
      for (int k = 0; k < 4; ++k) {
        if (s[i][j] == '.' && s[i + dx[k]][j + dy[k]] == '.' &&
            0 <= i + dx[k] && i + dx[k] < H && 0 <= j + dy[k] &&
            j + dy[k] < W) {
          u.unite(i * H + j, (i + dx[k]) * H + j + dy[k]);
        }
      }
    }
  }
  int d[H][W];
  for (int i = 0; i < H; ++i) {
    for (int j = 0; j < W; ++j) {
      if (s[i][j] == '.') {
        int x = u.root(i * H + j);
        d[i][j] = x;
      }
    }
  }
  vector<vector<int>> g(H * W);
  for (int i = 0; i < H; ++i) {
    for (int j = 0; j < W; ++j) {
      for (int k = -2; k <= 2; ++k) {
        for (int l = -2; l <= 2; ++l) {
          if (0 <= i + k && i + k < H && 0 <= j + l && j + l < W &&
              s[i][j] == '.' && s[i + k][j + l] == '.' &&
              d[i][j] != d[i + k][j + l]) {
            g[d[i][j]].push_back(d[i + k][j + l]);
            g[d[i + k][j + l]].push_back(d[i][j]);
          }
        }
      }
    }
  }
  vector<int> ans(H * W, -1);
  queue<int> q;
  int x = u.root(ch * H + cw), y = u.root(dh * H + dw);
  ans[x] = 0;
  q.push(x);
  while (!q.empty()) {
    int v = q.front();
    q.pop();
    for (int nv : g[v]) {
      if (ans[nv] != -1)
        continue;
      ans[nv] = ans[v] + 1;
      q.push(nv);
    }
  }
  cout << ans[y] << endl;
}