Problem p03855 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <iostream>
#include <map>
#define flush fflush(stdout)
using namespace std;
typedef long long ll;
typedef pair<int, int> P;
typedef pair<ll, ll> Pl;
const int mod = (int)1e9 + 7, INF = (int)1e9;
const int di[4] = {1, 0, -1, 0}, dj[4] = {0, 1, 0, -1};

#define N 100005
class uf {
private:
  int par[N] = {}, r[N] = {}, size[N] = {};

public:
  uf(int n) {
    int i;
    for (i = 0; i < n; i++) {
      par[i] = i;
      size[i] = 1;
    }
  }

  int root(int a) {
    if (par[a] == a)
      return a;
    return par[a] = root(par[a]);
  }

  void unite(int a, int b) {
    a = root(a);
    b = root(b);
    if (a == b)
      return;
    if (r[a] > r[b]) {
      par[b] = a;
      r[a]++;
      size[a] += size[b];
    } else {
      par[a] = b;
      r[b]++;
      size[b] += size[a];
    }
  }

  int show_size(int a) { return size[root(a)]; }

  int group(int n) {
    int i, t, res = 0;
    bool u[N] = {false};
    for (i = 0; i < n; i++) {
      t = root(i);
      if (!u[t]) {
        res++;
        u[t] = true;
      }
    }
    return res;
  }

  bool isroot(int a) { return par[a] == a; }
};

int main(void) {
  int n, k, l, i, p, q, r, s;
  map<P, int> pm;

  scanf("%d%d%d", &n, &k, &l);

  uf ro(n), tr(n);

  for (i = 0; i < k; i++) {
    scanf("%d%d", &p, &q);
    ro.unite(p - 1, q - 1);
  }
  for (i = 0; i < l; i++) {
    scanf("%d%d", &r, &s);
    tr.unite(r - 1, s - 1);
  }

  for (i = 0; i < n; i++) {
    pm[P(ro.root(i), tr.root(i))]++;
  }

  for (i = 0; i < n; i++) {
    printf("%d ", pm[P(ro.root(i), tr.root(i))]);
  }
  printf("\n");

  return 0;
}

Fixed submission:
#include <algorithm>
#include <iostream>
#include <map>
#define flush fflush(stdout)
using namespace std;
typedef long long ll;
typedef pair<int, int> P;
typedef pair<ll, ll> Pl;
const int mod = (int)1e9 + 7, INF = (int)1e9;
const int di[4] = {1, 0, -1, 0}, dj[4] = {0, 1, 0, -1};

#define N 200005
class uf {
private:
  int par[N] = {}, r[N] = {}, size[N] = {};

public:
  uf(int n) {
    int i;
    for (i = 0; i < n; i++) {
      par[i] = i;
      size[i] = 1;
    }
  }

  int root(int a) {
    if (par[a] == a)
      return a;
    return par[a] = root(par[a]);
  }

  void unite(int a, int b) {
    a = root(a);
    b = root(b);
    if (a == b)
      return;
    if (r[a] > r[b]) {
      par[b] = a;
      r[a]++;
      size[a] += size[b];
    } else {
      par[a] = b;
      r[b]++;
      size[b] += size[a];
    }
  }

  int show_size(int a) { return size[root(a)]; }

  int group(int n) {
    int i, t, res = 0;
    bool u[N] = {false};
    for (i = 0; i < n; i++) {
      t = root(i);
      if (!u[t]) {
        res++;
        u[t] = true;
      }
    }
    return res;
  }

  bool isroot(int a) { return par[a] == a; }
};

int main(void) {
  int n, k, l, i, p, q, r, s;
  map<P, int> pm;

  scanf("%d%d%d", &n, &k, &l);

  uf ro(n), tr(n);

  for (i = 0; i < k; i++) {
    scanf("%d%d", &p, &q);
    ro.unite(p - 1, q - 1);
  }
  for (i = 0; i < l; i++) {
    scanf("%d%d", &r, &s);
    tr.unite(r - 1, s - 1);
  }

  for (i = 0; i < n; i++) {
    pm[P(ro.root(i), tr.root(i))]++;
  }

  for (i = 0; i < n; i++) {
    printf("%d ", pm[P(ro.root(i), tr.root(i))]);
  }
  printf("\n");

  return 0;
}