Problem p04007 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cmath>
#include <map>
#include <queue>
#include <set>
#include <stdio.h>
#include <vector>

using namespace std;

// typedef long long LL;
typedef pair<int, int> P2;
typedef pair<pair<int, int>, int> P3;
typedef pair<pair<int, int>, pair<int, int>> P4;
#define Fst first
#define Snd second
#define MP(a, b) make_pair((a), (b))
#define M3P(a, b, c) make_pair(make_pair((a), (b)), (c))
#define M4P(a, b, c, d) make_pair(make_pair((a), (b)), make_pair((c), (d)));
#define Mx(a, b) ((a) > (b) ? (a) : (b))
#define Mn(a, b) ((a) < (b) ? (a) : (b))

const double EPS = 1e-10;
const int INF = 2147483647;

const int UF_MAX = 1000000;

class UF {
  int x[UF_MAX];

public:
  void dft() {
    for (int i = 0; i < UF_MAX; ++i)
      x[i] = -1;
  }

  int Boss(int a) {
    int s = a;
    while (x[s] > -1)
      s = x[s];
    if (s != a)
      x[a] = s;
    return s;
  }

  void Union(int a, int b) {
    int s = Boss(a);
    int t = Boss(b);
    if (s != t) {
      if (x[s] < x[t]) {
        x[s] += x[t];
        x[t] = s;
      } else {
        x[t] += x[s];
        x[s] = t;
      }
    }
  }

  bool Find(int a, int b) { return Boss(a) == Boss(b); }

  int Count(int a) {
    int b = 0;
    for (int i = 0; i < a; ++i)
      if (x[i] < 0)
        ++b;
    return b;
  }
};

int H, W;
int d[5] = {1, 0, -1, 0, 1};
bool p[500][500];
bool r[500][500];
char c;
vector<int> V;
int a;
UF T;

int main() {
  T.dft();
  scanf("%d%d", &H, &W);
  for (int i = 0; i < H; ++i) {
    for (int j = 0; j < W; ++j) {
      scanf(" %c", &c);
      p[i][j] = c == '#';
      if (p[i][j]) {
        ++a;
        V.push_back(i * 500 + j);
        if (i > 0 && p[i - 1][j])
          T.Union(i * 500 + j, (i - 1) * 500 + j);
        if (j > 0 && p[i][j - 1])
          T.Union(i * 500 + j, i * 500 + j - 1);
      }
    }
  }
  if (!p[1][1])
    r[1][1] = 1;
  for (int i = 0; i < a; ++i) {
    while (!T.Find(501, V[i])) {
      if (V[0] % 500 != V[i] % 500) {
        int x = V[i] + (V[0] % 500 < V[i] % 500 ? -1 : 1);
        if (!p[x / 500][x % 500])
          r[x / 500][x % 500] = 1;
        T.Union(V[i], x);
        V[i] = x;
      } else {
        int x = V[i] - 500;
        if (!p[x / 500][x % 500])
          r[x / 500][x % 500] = 1;
        T.Union(V[i], x);
        V[i] = x;
      }
      for (int j = 0; j < 4; ++j) {
        if (p[V[i] / 500 + d[j]][V[i] % 500 + d[j + 1]] ||
            r[V[i] / 500 + d[j]][V[i] % 500 + d[j + 1]])
          T.Union(V[i], V[i] + 500 * d[j] + d[j + 1]);
      }
    }
  }
  for (int i = 0; i < H; ++i) {
    for (int j = 0; j < W; ++j) {
      printf("%c", p[i][j] || r[i][j] ? '#' : '.');
    }
    printf("\n");
  }
  printf("\n");
  for (int i = 0; i < H; ++i) {
    for (int j = 0; j < W; ++j) {
      printf("%c", r[i][j] ? '.' : '#');
    }
    printf("\n");
  }
  return 0;
}


Fixed submission:
#include <algorithm>
#include <cmath>
#include <map>
#include <queue>
#include <set>
#include <stdio.h>
#include <vector>

using namespace std;

// typedef long long LL;
typedef pair<int, int> P2;
typedef pair<pair<int, int>, int> P3;
typedef pair<pair<int, int>, pair<int, int>> P4;
#define Fst first
#define Snd second
#define MP(a, b) make_pair((a), (b))
#define M3P(a, b, c) make_pair(make_pair((a), (b)), (c))
#define M4P(a, b, c, d) make_pair(make_pair((a), (b)), make_pair((c), (d)));
#define Mx(a, b) ((a) > (b) ? (a) : (b))
#define Mn(a, b) ((a) < (b) ? (a) : (b))

const double EPS = 1e-10;
const int INF = 2147483647;

const int UF_MAX = 1000000;

class UF {
  int x[UF_MAX];

public:
  void dft() {
    for (int i = 0; i < UF_MAX; ++i)
      x[i] = -1;
  }

  int Boss(int a) {
    int s = a;
    while (x[s] > -1)
      s = x[s];
    if (s != a)
      x[a] = s;
    return s;
  }

  void Union(int a, int b) {
    int s = Boss(a);
    int t = Boss(b);
    if (s != t) {
      if (x[s] < x[t]) {
        x[s] += x[t];
        x[t] = s;
      } else {
        x[t] += x[s];
        x[s] = t;
      }
    }
  }

  bool Find(int a, int b) { return Boss(a) == Boss(b); }

  int Count(int a) {
    int b = 0;
    for (int i = 0; i < a; ++i)
      if (x[i] < 0)
        ++b;
    return b;
  }
};

int H, W;
int d[5] = {1, 0, -1, 0, 1};
bool p[500][500];
bool r[500][500];
char c;
vector<int> V;
int a;
UF T;

int main() {
  T.dft();
  scanf("%d%d", &H, &W);
  for (int i = 0; i < H; ++i) {
    for (int j = 0; j < W; ++j) {
      scanf(" %c", &c);
      p[i][j] = c == '#';
      if (p[i][j]) {
        ++a;
        V.push_back(i * 500 + j);
        if (i > 0 && p[i - 1][j])
          T.Union(i * 500 + j, (i - 1) * 500 + j);
        if (j > 0 && p[i][j - 1])
          T.Union(i * 500 + j, i * 500 + j - 1);
      }
    }
  }
  if (!p[1][1])
    r[1][1] = 1;
  for (int i = 0; i < a; ++i) {
    while (!T.Find(501, V[i])) {
      if (1 != V[i] % 500) {
        int x = V[i] - 1;
        if (!p[x / 500][x % 500])
          r[x / 500][x % 500] = 1;
        T.Union(V[i], x);
        V[i] = x;
      } else {
        int x = V[i] - 500;
        if (!p[x / 500][x % 500])
          r[x / 500][x % 500] = 1;
        T.Union(V[i], x);
        V[i] = x;
      }
      for (int j = 0; j < 4; ++j) {
        if (p[V[i] / 500 + d[j]][V[i] % 500 + d[j + 1]] ||
            r[V[i] / 500 + d[j]][V[i] % 500 + d[j + 1]])
          T.Union(V[i], V[i] + 500 * d[j] + d[j + 1]);
      }
    }
  }
  for (int i = 0; i < H; ++i) {
    for (int j = 0; j < W; ++j) {
      printf("%c", p[i][j] || r[i][j] ? '#' : '.');
    }
    printf("\n");
  }
  printf("\n");
  for (int i = 0; i < H; ++i) {
    for (int j = 0; j < W; ++j) {
      printf("%c", r[i][j] ? '.' : '#');
    }
    printf("\n");
  }
  return 0;
}