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

#include <iostream>
#include <map>
#include <set>
#include <vector>
using namespace std;

int field[52][52];
int memo[52][52];

void dfs(int j, int i) {
  if (memo[i][j] || !field[i][j])
    return;
  memo[i][j] = 1;
  dfs(j - 1, i - 1);
  dfs(j, i - 1);
  dfs(j + 1, i - 1);
  dfs(j - 1, i);
  dfs(j + 1, i);
  dfs(j - 1, i + 1);
  dfs(j, i + 1);
  dfs(j + 1, i + 1);
}

int main(void) {
  int w, h;
  while (cin >> w >> h, w || h) {
    for (int i = 0; i < h; ++i) {
      for (int j = 0; j < w; ++j) {
        cin >> field[i][j];
        memo[i][j] = 0;
      }
    }
    int ans = 0;
    for (int i = 0; i < h; ++i) {
      for (int j = 0; j < w; ++j) {
        if (field[i][j] && !memo[i][j]) {
          dfs(j, i);
          ++ans;
        }
      }
    }
    cout << ans << endl;
  }
  return 0;
}

Error: 0
!0
!02
!20
!222
!222
!20300
!20000
!20404
!20040
!22202
!20202
!20202
!20222
!20304
!00000
!50607
!00000
!809010


Fixed submission:

#include <iostream>
#include <map>
#include <set>
#include <vector>
using namespace std;

void add_label(map<int, int> &tbl, int a, int b) {
  if (a == b)
    return;
  if (a > b)
    tbl[a] = b;
  else
    tbl[b] = a;
}

int main(void) {
  int w, h;
  while (cin >> w >> h, w || h) {
    vector<vector<int>> field(h);
    vector<vector<int>> labeled(h);
    for (int i = 0; i < h; ++i) {
      field[i] = vector<int>(w);
      labeled[i] = vector<int>(w);
      for (int j = 0; j < w; ++j) {
        cin >> field[i][j];
        labeled[i][j] = 0;
      }
    }
    int label = 1;
    map<int, int> tbl;
    for (int i = 0; i < h; ++i) {
      for (int j = 0; j < w; ++j) {
        if (field[i][j]) {
          bool f = false;
          if (i) {
            if (j && labeled[i - 1][j - 1]) {
              if (!f)
                labeled[i][j] = labeled[i - 1][j - 1];
              f = true;
            }
            if (labeled[i - 1][j]) {
              if (!f)
                labeled[i][j] = labeled[i - 1][j];
              else
                add_label(tbl, labeled[i][j], labeled[i - 1][j]);
              f = true;
            }
            if (j < w - 1 && labeled[i - 1][j + 1]) {
              if (!f)
                labeled[i][j] = labeled[i - 1][j + 1];
              else
                add_label(tbl, labeled[i][j], labeled[i - 1][j + 1]);
              f = true;
            }
            if (j && labeled[i][j - 1]) {
              if (!f)
                labeled[i][j] = labeled[i][j - 1];
              else
                add_label(tbl, labeled[i][j], labeled[i][j - 1]);
              f = true;
            }
            if (!f)
              labeled[i][j] = ++label;
          } else {
            if (j && labeled[i][j - 1]) {
              if (!f)
                labeled[i][j] = labeled[i][j - 1];
              else
                add_label(tbl, labeled[i][j], labeled[i][j - 1]);
              f = true;
            }
            if (!f)
              labeled[i][j] = ++label;
          }
        }
      }
    }
    for (auto x : tbl) {
      int a = x.first;
      int b = x.second;
      while (tbl.find(b) != tbl.end()) {
        b = tbl.find(b)->second;
      }
      for (int i = 0; i < h; ++i) {
        for (int j = 0; j < w; ++j) {
          if (labeled[i][j] == a)
            labeled[i][j] = b;
        }
      }
    }

    for (int i = 0; i < h; ++i) {
      cerr << "!";
      for (int j = 0; j < w; ++j) {
        cerr << labeled[i][j];
      }
      cerr << endl;
    }

    set<int> nums;
    nums.insert(0);
    for (int i = 0; i < h; ++i) {
      for (int j = 0; j < w; ++j) {
        nums.insert(labeled[i][j]);
      }
    }
    cout << nums.size() - 1 << endl;
  }
  return 0;
}