Problem p00225 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cstdio>
#include <iostream>
#include <string>
#include <vector>
using namespace std;

struct UnionFind {
  int n;
  vector<int> parent;
  vector<int> rank;
  vector<int> num;
  int find(int x) {
    if (parent[x] == x)
      return x;
    return parent[x] = find(parent[x]);
  }
  UnionFind(int n_) {
    n = n_;
    parent.resize(n);
    for (int i = 0; i < n; i++)
      parent[i] = i;
    rank.assign(n, 0);
    num.assign(n, 1);
  }
  void unite(int x, int y) {
    if ((x = find(x)) != (y = find(y))) {
      if (rank[x] < rank[y]) {
        parent[x] = y;
        num[y] += num[x];
      } else {
        parent[y] = x;
        if (rank[x] == rank[y])
          rank[x]++;
        num[x] += num[y];
      }
      n--;
    }
  }
  bool same(int x, int y) { return find(x) == find(y); }
  int get() { return n; }
  int get(int x) { return num[find(x)]; }
};

int main() {
  int n;
  while (scanf("%d", &n), n) {
    UnionFind uf(26);
    vector<int> in_deg(26), out_deg(26);
    for (int i = 0; i < n; i++) {
      string s;
      cin >> s;
      int a = s[0] - 'a';
      int b = s.back() - 'a';
      in_deg[a]++, out_deg[b]++;
      uf.unite(a, b);
    }
    bool ok = true;
    int cnt = 0;
    for (int i = 0; i < 26; i++)
      if (in_deg[i] > 0 || out_deg[i] > 0)
        cnt++;
    cerr << cnt << endl;
    for (int i = 0; i < 26; i++) {
      if (in_deg[i] > 0 || out_deg[i] > 0) {
        if (uf.get(i) != cnt) {
          ok = false;
          break;
        }
      }
    }
    for (int i = 0; i < 26; i++)
      ok &= in_deg[i] == out_deg[i];
    puts(ok ? "OK" : "NG");
  }
  return 0;
}

Fixed submission:
#include <algorithm>
#include <cstdio>
#include <iostream>
#include <string>
#include <vector>
using namespace std;

struct UnionFind {
  int n;
  vector<int> parent;
  vector<int> rank;
  vector<int> num;
  int find(int x) {
    if (parent[x] == x)
      return x;
    return parent[x] = find(parent[x]);
  }
  UnionFind(int n_) {
    n = n_;
    parent.resize(n);
    for (int i = 0; i < n; i++)
      parent[i] = i;
    rank.assign(n, 0);
    num.assign(n, 1);
  }
  void unite(int x, int y) {
    if ((x = find(x)) != (y = find(y))) {
      if (rank[x] < rank[y]) {
        parent[x] = y;
        num[y] += num[x];
      } else {
        parent[y] = x;
        if (rank[x] == rank[y])
          rank[x]++;
        num[x] += num[y];
      }
      n--;
    }
  }
  bool same(int x, int y) { return find(x) == find(y); }
  int get() { return n; }
  int get(int x) { return num[find(x)]; }
};

int main() {
  int n;
  while (scanf("%d", &n), n) {
    UnionFind uf(26);
    vector<int> in_deg(26), out_deg(26);
    for (int i = 0; i < n; i++) {
      string s;
      cin >> s;
      int a = s[0] - 'a';
      int b = s.back() - 'a';
      in_deg[a]++, out_deg[b]++;
      uf.unite(a, b);
    }
    bool ok = true;
    int cnt = 0;
    for (int i = 0; i < 26; i++)
      if (in_deg[i] > 0 || out_deg[i] > 0)
        cnt++;
    for (int i = 0; i < 26; i++) {
      if (in_deg[i] > 0 || out_deg[i] > 0) {
        if (uf.get(i) != cnt) {
          ok = false;
          break;
        }
      }
    }
    for (int i = 0; i < 26; i++)
      ok &= in_deg[i] == out_deg[i];
    puts(ok ? "OK" : "NG");
  }
  return 0;
}