Problem p03855 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>

const double PI = 3.14159265358979323846;
using namespace std;
typedef long long ll;
const double EPS = 1e-9;
#define rep(i, n) for (int i = 0; i < (n); ++i)
// #define rep(i, n) for (ll i = 0; i < (n); ++i)
// typedef pair<ll, ll> P;
typedef pair<double, ll> P;
const ll INF = 10e17;
#define cmin(x, y) x = min(x, y)
#define cmax(x, y) x = max(x, y)
#define ret() return 0;

std::istream &operator>>(std::istream &in, set<int> &o) {
  ll a;
  in >> a;
  o.insert(a);
  return in;
}

std::istream &operator>>(std::istream &in, queue<int> &o) {
  ll a;
  in >> a;
  o.push(a);
  return in;
}

bool contain(set<int> &s, int a) { return s.find(a) != s.end(); }

// ifstream myfile("C:\\Users\\riku\\Downloads\\0_00.txt");
// ofstream outfile("log.txt");
// outfile << setw(6) << setfill('0') << prefecture << setw(6) << setfill('0')
// << rank << endl;
//  std::cout << std::bitset<8>(9);

// const ll mod = 1e10;
typedef priority_queue<string, vector<string>, greater<string>> PQ_ASK;

class UnionFind {
public:
  // 親の番号を格納する。親だった場合-size
  vector<int> parents;

  UnionFind(int n) { parents = vector<int>(n, -1); }

  // aがどのグループに属しているか
  int root(int a) {
    if (parents[a] < 0) {
      return a;
    }
    return parents[a] = root(parents[a]);
  }

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

  // aとbをくっつける
  bool connect(int a, int b) {
    int ra = root(a);
    int rb = root(b);
    if (ra == rb) {
      return false;
    }
    // 大きいほうにA
    if (size(ra) < size(rb)) {
      swap(ra, rb);
    }
    parents[ra] += parents[rb];
    parents[rb] = ra;
    return true;
  }

  bool is_union(int a, int b) { return root(a) == root(b); }
};

int main() {
  int n, k, l;

  cin >> n >> k >> l;

  UnionFind road(n), train(n);
  rep(_, k) {
    int a, b;
    cin >> a >> b;
    a--;
    b--;

    road.connect(a, b);
  }

  rep(_, l) {
    int a, b;
    cin >> a >> b;
    a--;
    b--;

    train.connect(a, b);
  }

  rep(i, n) {
    int ans = 0;
    rep(j, n) {
      if (road.is_union(i, j) && train.is_union(i, j))
        ans++;
    }
    cout << ans << endl;
  }
}


Fixed submission:
#include <bits/stdc++.h>

const double PI = 3.14159265358979323846;
using namespace std;
typedef long long ll;
const double EPS = 1e-9;
#define rep(i, n) for (int i = 0; i < (n); ++i)
// #define rep(i, n) for (ll i = 0; i < (n); ++i)
// typedef pair<ll, ll> P;
typedef pair<double, ll> P;
const ll INF = 10e17;
#define cmin(x, y) x = min(x, y)
#define cmax(x, y) x = max(x, y)
#define ret() return 0;

std::istream &operator>>(std::istream &in, set<int> &o) {
  ll a;
  in >> a;
  o.insert(a);
  return in;
}

std::istream &operator>>(std::istream &in, queue<int> &o) {
  ll a;
  in >> a;
  o.push(a);
  return in;
}

bool contain(set<int> &s, int a) { return s.find(a) != s.end(); }

// ifstream myfile("C:\\Users\\riku\\Downloads\\0_00.txt");
// ofstream outfile("log.txt");
// outfile << setw(6) << setfill('0') << prefecture << setw(6) << setfill('0')
// << rank << endl;
//  std::cout << std::bitset<8>(9);

// const ll mod = 1e10;
typedef priority_queue<string, vector<string>, greater<string>> PQ_ASK;

class UnionFind {
public:
  // 親の番号を格納する。親だった場合-size
  vector<int> parents;

  UnionFind(int n) { parents = vector<int>(n, -1); }

  // aがどのグループに属しているか
  int root(int a) {
    if (parents[a] < 0) {
      return a;
    }
    return parents[a] = root(parents[a]);
  }

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

  // aとbをくっつける
  bool connect(int a, int b) {
    int ra = root(a);
    int rb = root(b);
    if (ra == rb) {
      return false;
    }
    // 大きいほうにA
    if (size(ra) < size(rb)) {
      swap(ra, rb);
    }
    parents[ra] += parents[rb];
    parents[rb] = ra;
    return true;
  }

  bool is_union(int a, int b) { return root(a) == root(b); }
};

int main() {
  int n, k, l;

  cin >> n >> k >> l;

  UnionFind road(n), train(n);
  rep(_, k) {
    int a, b;
    cin >> a >> b;
    a--;
    b--;

    road.connect(a, b);
  }

  rep(_, l) {
    int a, b;
    cin >> a >> b;
    a--;
    b--;

    train.connect(a, b);
  }

  vector<int> rr(n), tr(n);
  rep(i, n) rr[i] = road.root(i);
  rep(i, n) tr[i] = train.root(i);

  map<P, int> m;
  rep(i, n) m[P(rr[i], tr[i])]++;

  rep(i, n) cout << m[P(rr[i], tr[i])] << endl;
}