Problem p03921 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define ALL(A) A.begin(), A.end()

using namespace std;

typedef long long ll;
typedef pair<int, int> P;

const int MAX_N = (int)1e5 + 5;
const int MAX_M = (int)1e3 + 5;

int a[MAX_N];
// n 要素で初期化
void init(int n) {
  for (int i = 0; i < n; ++i) {
    a[i] = -1;
  } // end for
}

// 木の根を求める
int find(int x) {
  if (a[x] < 0) {
    return x;
  } else {
    return (a[x] = find(a[x]));
  } // end if
}

// x と y の属する集合を併合
void unite(int x, int y) {
  x = find(x);
  y = find(y);
  if (x != y) {
    a[x] += a[y];
    a[y] = x;
  } // end if
}

// x と y が同じ集合に属するか
bool same(int x, int y) { return find(x) == find(y); }

int size(int x) { return -a[find(x)]; }

struct PERSON {
  int K;
  vector<int> L;
};

PERSON G[MAX_N];
vector<int> lang[MAX_M];

int main() {
  rep(i, MAX_M) lang[i].clear();
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  int N;
  cin >> N;
  int M;
  cin >> M;

  rep(i, N) {
    int K;
    cin >> K;
    G[i].K = K;
    vector<int> L(K, 0);
    rep(j, K) {
      int l;
      cin >> l;
      --l;
      L[j] = l;
    } // end rep
    G[i].L = L;
  } // end rep

  rep(i, N) {
    int K = G[i].K;
    rep(j, K) {
      int l = G[i].L[j];
      lang[l].push_back(i);
    } // end rep
  }   // end rep

  init(N);
  for (int j = 0; j < M; ++j) {
    if (lang[j].empty())
      continue;
    int u = lang[j][0];
    for (int i = 1; i < lang[j].size(); ++i) {
      unite(u, lang[j][i]);
    } // end for
  }   // end for

  cout << (size(0) == N ? "YES" : "NO") << endl;

  return 0;
}

Fixed submission:
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define ALL(A) A.begin(), A.end()

using namespace std;

typedef long long ll;
typedef pair<int, int> P;

const int MAX_N = (int)1e5 + 5;
const int MAX_M = (int)1e5 + 5;

int a[MAX_N];
// n 要素で初期化
void init(int n) {
  for (int i = 0; i < n; ++i) {
    a[i] = -1;
  } // end for
}

// 木の根を求める
int find(int x) {
  if (a[x] < 0) {
    return x;
  } else {
    return (a[x] = find(a[x]));
  } // end if
}

// x と y の属する集合を併合
void unite(int x, int y) {
  x = find(x);
  y = find(y);
  if (x != y) {
    a[x] += a[y];
    a[y] = x;
  } // end if
}

// x と y が同じ集合に属するか
bool same(int x, int y) { return find(x) == find(y); }

int size(int x) { return -a[find(x)]; }

struct PERSON {
  int K;
  vector<int> L;
};

PERSON G[MAX_N];
vector<int> lang[MAX_M];

int main() {
  rep(i, MAX_M) lang[i].clear();
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  int N;
  cin >> N;
  int M;
  cin >> M;

  rep(i, N) {
    int K;
    cin >> K;
    G[i].K = K;
    vector<int> L(K, 0);
    rep(j, K) {
      int l;
      cin >> l;
      --l;
      L[j] = l;
    } // end rep
    G[i].L = L;
  } // end rep

  rep(i, N) {
    int K = G[i].K;
    rep(j, K) {
      int l = G[i].L[j];
      lang[l].push_back(i);
    } // end rep
  }   // end rep

  init(N);
  for (int j = 0; j < M; ++j) {
    if (lang[j].empty())
      continue;
    int u = lang[j][0];
    for (int i = 1; i < lang[j].size(); ++i) {
      unite(u, lang[j][i]);
    } // end for
  }   // end for

  cout << (size(0) == N ? "YES" : "NO") << endl;

  return 0;
}