Problem p02579 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;
#define FIN                                                                    \
  ios_base::sync_with_stdio(false);                                            \
  cin.tie(0);                                                                  \
  cout.tie(0);

typedef long long ll;
typedef vector<ll> vll;
typedef vector<vll> vvll;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<vvi> vvvi;
typedef pair<int, int> ii;
typedef vector<ii> vii;
typedef vector<string> vs;
typedef vector<bool> vb;
typedef map<int, int> mii;
typedef map<ll, ll> mll;
typedef set<ii> sii;
typedef set<int> si;
typedef priority_queue<int> pqi;
typedef priority_queue<ii> pqii;
typedef queue<ii> qii;

const int INF = 1000000010;
const ll MOD = 1000000007;

class UnionFind {
private:
  vi p, rank;

public:
  UnionFind(int N) {
    rank.assign(N, 0);
    p.assign(N, 0);
    for (int i = 0; i < N; i++)
      p[i] = i;
  }
  int findSet(int i) { return (p[i] == i) ? i : (p[i] = findSet(p[i])); }
  bool isSameSet(int i, int j) { return findSet(i) == findSet(j); }
  void unionSet(int i, int j) {
    if (!isSameSet(i, j)) {
      int x = findSet(i), y = findSet(j);
      if (rank[x] > rank[y]) {
        p[y] = x;
      } else {
        p[x] = y;
        if (rank[x] == rank[y])
          rank[y]++;
      }
    }
  }
};

int main() {
  FIN

      int n,
      m, i, j, a, b, x, y, p, q, c = 0;
  cin >> n >> m;
  cin >> a >> b;
  cin >> x >> y;
  vs tb(n);
  vvi pr(n, vi(m, -1));
  UnionFind UF(n * m);

  for (i = 0; i < n; i++) {
    cin >> tb[i];
    for (j = 0; j < m; j++) {
      if (tb[i][j] == '.') {
        if (i > 0 and tb[i - 1][j] == '.')
          UF.unionSet(i * m + j, (i - 1) * m + j);
        if (j > 0 and tb[i][j - 1] == '.')
          UF.unionSet(i * m + j, i * m + (j - 1));
      }
    }
  }

  sii ed;
  vvi gf(n * m);
  for (i = 0; i < n; i++) {
    for (j = 0; j < m; j++) {
      if (tb[i][j] == '.')
        pr[i][j] = UF.findSet(i * m + j);
    }
  }

  for (i = 0; i < n; i++) {
    for (j = 0; j < m; j++) {
      if (pr[i][j] != -1) {
        for (p = min(n - 1, i + 2); p >= max(0, i - 2); p--) {
          for (q = min(m - 1, j + 2); q >= max(0, j - 2); q--) {
            if (pr[p][q] != -1 and pr[i][j] != pr[p][q]) {
              auto it =
                  ed.find(ii(min(pr[i][j], pr[p][q]), max(pr[i][j], pr[p][q])));
              if (it == ed.end()) {
                gf[pr[i][j]].push_back(pr[p][q]);
                gf[pr[p][q]].push_back(pr[i][j]);
              }
            }
          }
        }
      }
    }
  }

  a--, b--, x--, y--;
  if (pr[a][b] != pr[x][y]) {
    qii tr;
    tr.push(ii(pr[a][b], 0));
    vi vis(n);
    vis[pr[a][b]] = 1;
    while (!tr.empty()) {
      ii e = tr.front();
      tr.pop();
      for (i = 0; i < (int)gf[e.first].size(); i++) {
        if (vis[gf[e.first][i]] == 0) {
          if (gf[e.first][i] == pr[x][y]) {
            cout << e.second + 1 << "\n";
            return 0;
          }
          vis[gf[e.first][i]] = 1;
          tr.push(ii(gf[e.first][i], e.second + 1));
        }
      }
    }
    c = -1;
  }
  cout << c << "\n";

  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;
#define FIN                                                                    \
  ios_base::sync_with_stdio(false);                                            \
  cin.tie(0);                                                                  \
  cout.tie(0);

typedef long long ll;
typedef vector<ll> vll;
typedef vector<vll> vvll;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<vvi> vvvi;
typedef pair<int, int> ii;
typedef vector<ii> vii;
typedef vector<string> vs;
typedef vector<bool> vb;
typedef map<int, int> mii;
typedef map<ll, ll> mll;
typedef set<ii> sii;
typedef set<int> si;
typedef priority_queue<int> pqi;
typedef priority_queue<ii> pqii;
typedef queue<ii> qii;

const int INF = 1000000010;
const ll MOD = 1000000007;

class UnionFind {
private:
  vi p, rank;

public:
  UnionFind(int N) {
    rank.assign(N, 0);
    p.assign(N, 0);
    for (int i = 0; i < N; i++)
      p[i] = i;
  }
  int findSet(int i) { return (p[i] == i) ? i : (p[i] = findSet(p[i])); }
  bool isSameSet(int i, int j) { return findSet(i) == findSet(j); }
  void unionSet(int i, int j) {
    if (!isSameSet(i, j)) {
      int x = findSet(i), y = findSet(j);
      if (rank[x] > rank[y]) {
        p[y] = x;
      } else {
        p[x] = y;
        if (rank[x] == rank[y])
          rank[y]++;
      }
    }
  }
};

int main() {
  FIN

      int n,
      m, i, j, a, b, x, y, p, q, c = 0;
  cin >> n >> m;
  cin >> a >> b;
  cin >> x >> y;
  vs tb(n);
  vvi pr(n, vi(m, -1));
  UnionFind UF(n * m);

  for (i = 0; i < n; i++) {
    cin >> tb[i];
    for (j = 0; j < m; j++) {
      if (tb[i][j] == '.') {
        if (i > 0 and tb[i - 1][j] == '.')
          UF.unionSet(i * m + j, (i - 1) * m + j);
        if (j > 0 and tb[i][j - 1] == '.')
          UF.unionSet(i * m + j, i * m + (j - 1));
      }
    }
  }

  sii ed;
  vvi gf(n * m);
  for (i = 0; i < n; i++) {
    for (j = 0; j < m; j++) {
      if (tb[i][j] == '.')
        pr[i][j] = UF.findSet(i * m + j);
    }
  }

  for (i = 0; i < n; i++) {
    for (j = 0; j < m; j++) {
      if (pr[i][j] != -1) {
        for (p = min(n - 1, i + 2); p >= max(0, i - 2); p--) {
          for (q = min(m - 1, j + 2); q >= max(0, j - 2); q--) {
            if (pr[p][q] != -1 and pr[i][j] != pr[p][q]) {
              auto it =
                  ed.find(ii(min(pr[i][j], pr[p][q]), max(pr[i][j], pr[p][q])));
              if (it == ed.end()) {
                gf[pr[i][j]].push_back(pr[p][q]);
                gf[pr[p][q]].push_back(pr[i][j]);
              }
            }
          }
        }
      }
    }
  }

  a--, b--, x--, y--;
  if (pr[a][b] != pr[x][y]) {
    qii tr;
    tr.push(ii(pr[a][b], 0));
    vi vis(n * m);
    vis[pr[a][b]] = 1;
    while (!tr.empty()) {
      ii e = tr.front();
      tr.pop();
      for (i = 0; i < (int)gf[e.first].size(); i++) {
        if (vis[gf[e.first][i]] == 0) {
          if (gf[e.first][i] == pr[x][y]) {
            cout << e.second + 1 << "\n";
            return 0;
          }
          vis[gf[e.first][i]] = 1;
          tr.push(ii(gf[e.first][i], e.second + 1));
        }
      }
    }
    c = -1;
  }
  cout << c << "\n";

  return 0;
}