Problem p03855 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
#ifdef __mr__
#include "prettyprint.hpp"
#else
#define endl '\n'
#endif
#define len(x) (uint)(x).size()
#define int int32_t
#define uint uint32_t
#define ulong uint64_t
#define long int64_t
#define maxof(x) numeric_limits<x>::max()
#define minof(x) numeric_limits<x>::min()
using namespace std;
const ulong mod = 1000000007ul;

struct unionfind {
  size_t length;
  uint32_t *roots, *ranks;
  unionfind(size_t n) {
    length = n;
    roots = new uint32_t[n];
    ranks = new uint32_t[n];
    for (int i = 0; i < n; ++i) {
      roots[i] = i;
      ranks[i] = 0;
    }
  }
  void connect(uint32_t a, uint32_t b) {
    uint32_t aroot = find_root(a);
    uint32_t broot = find_root(b);
    if (aroot == broot)
      return;
    if (ranks[aroot] < ranks[broot]) {
      roots[aroot] = broot;
    } else if (ranks[aroot] > ranks[broot]) {
      roots[broot] = aroot;
    } else {
      roots[broot] = aroot;
      ++ranks[aroot];
    }
  }
  bool is_connected(uint32_t a, uint32_t b) {
    return find_root(a) == find_root(b);
  }
  int32_t find_root(uint32_t a) {
    while (roots[a] != a) {
      roots[a] = roots[roots[a]];
      a = roots[a];
    }
    return a;
  }
};

int main(int argc, char const *argv[]) {
#ifndef __mr__
  ios::sync_with_stdio(0);
  cin.tie(0);
#endif
  int n, k, l;
  cin >> n >> k >> l;
  unionfind roads(n);
  vector<int> us;
  vector<int> vs;
  for (int i = 0; i < k; ++i) {
    int u, v;
    cin >> u >> v;
    --u;
    --v;
    us.push_back(u);
    vs.push_back(v);
    roads.connect(u, v);
  }
  unionfind railways(n);
  unionfind both(n);
  for (int i = 0; i < l; ++i) {
    int u, v;
    cin >> u >> v;
    --u;
    --v;
    us.push_back(u);
    vs.push_back(v);
    railways.connect(u, v);
  }
  for (int i = 0; i < k + l; ++i) {
    if (roads.is_connected(us[i], vs[i]) && railways.is_connected(us[i], vs[i]))
      both.connect(us[i], vs[i]);
  }

  map<int, set<int>> roads_groups;
  map<int, set<int>> railways_groups;
  for (int i = 0; i < n; ++i) {
    roads_groups[roads.find_root(i)].insert(i);
    railways_groups[railways.find_root(i)].insert(i);
  }
  //    cout << roads_groups << endl;
  //    cout << railways_groups << endl;
  map<pair<int, int>, int> intersected_sets;
  for (int i = 0; i < n; ++i) {
    if (intersected_sets.find(
            make_pair(roads.find_root(i), railways.find_root(i))) !=
        intersected_sets.end()) {
      continue;
    }
    vector<int> inter(max(roads_groups[roads.find_root(i)].size(),
                          railways_groups[railways.find_root(i)].size()));
    int size = distance(
        inter.begin(),
        set_intersection(roads_groups[roads.find_root(i)].begin(),
                         roads_groups[roads.find_root(i)].end(),
                         railways_groups[railways.find_root(i)].begin(),
                         railways_groups[railways.find_root(i)].end(),
                         inter.begin()));
    intersected_sets[make_pair(roads.find_root(i), railways.find_root(i))] =
        size;
  }
  for (int i = 0; i < n; ++i) {
    cout << intersected_sets[make_pair(roads.find_root(i),
                                       railways.find_root(i))]
         << ' ';
  }
  cout << endl;

  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
#ifdef __mr__
#include "prettyprint.hpp"
#else
#define endl '\n'
#endif
#define len(x) (uint)(x).size()
#define int int32_t
#define uint uint32_t
#define ulong uint64_t
#define long int64_t
#define maxof(x) numeric_limits<x>::max()
#define minof(x) numeric_limits<x>::min()
using namespace std;
const ulong mod = 1000000007ul;

struct unionfind {
  size_t length;
  uint32_t *roots, *ranks;
  unionfind(size_t n) {
    length = n;
    roots = new uint32_t[n];
    ranks = new uint32_t[n];
    for (int i = 0; i < n; ++i) {
      roots[i] = i;
      ranks[i] = 0;
    }
  }
  void connect(uint32_t a, uint32_t b) {
    uint32_t aroot = find_root(a);
    uint32_t broot = find_root(b);
    if (aroot == broot)
      return;
    if (ranks[aroot] < ranks[broot]) {
      roots[aroot] = broot;
    } else if (ranks[aroot] > ranks[broot]) {
      roots[broot] = aroot;
    } else {
      roots[broot] = aroot;
      ++ranks[aroot];
    }
  }
  bool is_connected(uint32_t a, uint32_t b) {
    return find_root(a) == find_root(b);
  }
  int32_t find_root(uint32_t a) {
    while (roots[a] != a) {
      roots[a] = roots[roots[a]];
      a = roots[a];
    }
    return a;
  }
};

int main(int argc, char const *argv[]) {
#ifndef __mr__
  ios::sync_with_stdio(0);
  cin.tie(0);
#endif
  int n, k, l;
  cin >> n >> k >> l;
  unionfind roads(n);
  vector<int> us;
  vector<int> vs;
  for (int i = 0; i < k; ++i) {
    int u, v;
    cin >> u >> v;
    --u;
    --v;
    us.push_back(u);
    vs.push_back(v);
    roads.connect(u, v);
  }
  unionfind railways(n);
  unionfind both(n);
  for (int i = 0; i < l; ++i) {
    int u, v;
    cin >> u >> v;
    --u;
    --v;
    us.push_back(u);
    vs.push_back(v);
    railways.connect(u, v);
  }
  for (int i = 0; i < k + l; ++i) {
    if (roads.is_connected(us[i], vs[i]) && railways.is_connected(us[i], vs[i]))
      both.connect(us[i], vs[i]);
  }

  map<int, set<int>> roads_groups;
  map<int, set<int>> railways_groups;
  for (int i = 0; i < n; ++i) {
    roads_groups[roads.find_root(i)].insert(i);
    railways_groups[railways.find_root(i)].insert(i);
  }
  //    cout << roads_groups << endl;
  //    cout << railways_groups << endl;
  map<pair<int, int>, int> intersected_sets;
  for (int i = 0; i < n; ++i) {
    ++intersected_sets[make_pair(roads.find_root(i), railways.find_root(i))];
  }
  for (int i = 0; i < n; ++i) {
    cout << intersected_sets[make_pair(roads.find_root(i),
                                       railways.find_root(i))]
         << ' ';
  }
  cout << endl;

  return 0;
}