Problem p00118 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;
#define FOR(i, k, n) for (int i = (k); i < (n); i++)
#define REP(i, n) FOR(i, 0, n)
#define ALL(a) begin(a), end(a)
#define MS(m, v) memset(m, v, sizeof(m))
#define D10 fixed << setprecision(10)
typedef vector<int> vi;
typedef vector<string> vs;
typedef pair<int, int> P;
typedef long long ll;
const ll INF = 114514810;
const ll MOD = 1000000007;
const double EPS = 1e-8;
const double PI = acos(-1.0);
struct edge {
  int from, to, cost;
  bool operator<(const edge &e) const { return cost < e.cost; }
  bool operator>(const edge &e) const { return cost > e.cost; }
};
int dx[] = {-1, 0, 0, 1};
int dy[] = {0, -1, 1, 0};
bool valid(int x, int y, int h, int w) {
  return (x >= 0 && y >= 0 && x < h && y < w);
}
///*************************************************************************************///
///*************************************************************************************///
///*************************************************************************************///

struct union_find {
  vector<int> par;
  union_find(int n) : par(n, -1) {}
  int find(int x) { return par[x] < 0 ? x : par[x] = find(par[x]); }
  void unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y)
      return;
    if (par[y] < par[x])
      swap(x, y);
    if (par[x] == par[y])
      par[x]--;
    par[y] = x;
    if (find(x) != find(y))
      par[find(y)] = x;
  }
  bool same(int x, int y) { return find(x) == find(y); };
  int count() {
    int cnt = 0;
    REP(i, par.size()) if (par[i] < 0) cnt++;
    return cnt;
  }
};

int main() {
  int h, w;
  while (cin >> h >> w, h) {
    union_find uft(h * w);
    vs fld(h);
    REP(i, h) cin >> fld[i];
    REP(i, h) REP(j, w) {
      REP(k, 4) {
        int nx = i + dx[k];
        int ny = j + dy[k];
        if (valid(nx, ny, h, w) && fld[i][j] == fld[nx][ny] &&
            !uft.same(i * h + j, nx * h + ny)) {
          uft.unite(i * h + j, nx * h + ny);
        }
      }
    }
    cout << uft.count() << endl;
  }
  return 0;
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;
#define FOR(i, k, n) for (int i = (k); i < (n); i++)
#define REP(i, n) FOR(i, 0, n)
#define ALL(a) begin(a), end(a)
#define MS(m, v) memset(m, v, sizeof(m))
#define D10 fixed << setprecision(10)
typedef vector<int> vi;
typedef vector<string> vs;
typedef pair<int, int> P;
typedef long long ll;
const ll INF = 114514810;
const ll MOD = 1000000007;
const double EPS = 1e-8;
const double PI = acos(-1.0);
struct edge {
  int from, to, cost;
  bool operator<(const edge &e) const { return cost < e.cost; }
  bool operator>(const edge &e) const { return cost > e.cost; }
};
int dx[] = {-1, 0, 0, 1};
int dy[] = {0, -1, 1, 0};
bool valid(int x, int y, int h, int w) {
  return (x >= 0 && y >= 0 && x < h && y < w);
}
///*************************************************************************************///
///*************************************************************************************///
///*************************************************************************************///

struct union_find {
  vector<int> par;
  union_find(int n) : par(n, -1) {}
  int find(int x) { return par[x] < 0 ? x : par[x] = find(par[x]); }
  void unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y)
      return;
    if (par[y] < par[x])
      swap(x, y);
    if (par[x] == par[y])
      par[x]--;
    par[y] = x;
    if (find(x) != find(y))
      par[find(y)] = x;
  }
  bool same(int x, int y) { return find(x) == find(y); };
  int count() {
    int cnt = 0;
    REP(i, par.size()) if (par[i] < 0) cnt++;
    return cnt;
  }
};

int main() {
  int h, w;
  while (cin >> h >> w, h) {
    union_find uft(h * w);
    vs fld(h);
    REP(i, h) cin >> fld[i];
    REP(i, h) REP(j, w) {
      REP(k, 4) {
        int nx = i + dx[k];
        int ny = j + dy[k];
        if (valid(nx, ny, h, w) && fld[i][j] == fld[nx][ny]) {
          uft.unite(i * w + j, nx * w + ny);
        }
      }
    }
    cout << uft.count() << endl;
  }
  return 0;
}