Problem p03857 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <map>
#include <set>
#include <utility>
#include <vector>
using namespace std;
int find(vector<int> &parent, int x) {
  if (parent[x] == x) {
    return x;
  } else {
    return (parent[x] = find(parent, parent[x]));
  }
}

void unite(vector<int> &parent, vector<int> &rank, int x, int y) {
  x = find(parent, x);
  y = find(parent, y);
  if (x == y)
    return;
  if (rank[x] < rank[y]) {
    parent[x] = y;
  } else {
    parent[y] = x;
    if (rank[x] == rank[y]) {
      rank[x]++;
    }
  }
}

bool same(vector<int> &parent, int x, int y) {
  return find(parent, x) == find(parent, y);
}

int main() {
  int N;
  int K, L;
  scanf("%d%d%d", &N, &K, &L);
  vector<pair<int, int>> pq;
  vector<pair<int, int>> rs;
  for (int i = 0; i < K; i++) {
    pair<int, int> temppq;
    scanf("%d%d", &(temppq.first), &(temppq.second));
    pq.push_back(temppq);
  }
  for (int i = 0; i < L; i++) {
    pair<int, int> temprs;
    scanf("%d%d", &(temprs.first), &(temprs.second));
    rs.push_back(temprs);
  }
  vector<int> parentpq(N + 1, 0);
  vector<int> rankpq(N + 1, 0);
  for (int i = 1; i <= N; i++) {
    parentpq[i] = i;
    rankpq[i] = 0;
  }
  vector<int> parentrs(N + 1, 0);
  vector<int> rankrs(N + 1, 0);
  for (int i = 1; i <= N; i++) {
    parentrs[i] = i;
    rankrs[i] = 0;
  }
  for (int i = 0; i < K; i++) {
    unite(parentpq, rankpq, pq[i].first, pq[i].second);
  }
  for (int i = 0; i < L; i++) {
    unite(parentrs, rankrs, rs[i].first, rs[i].second);
  }
  map<int, set<int>> pqsets;
  map<int, set<int>> rssets;
  for (int i = 1; i <= N; i++) {
    int rootpq = find(parentpq, i);
    int rootrs = find(parentrs, i);
    if (pqsets.find(rootpq) == pqsets.end()) {
      pqsets[rootpq] = set<int>();
      pqsets[rootpq].insert(rootpq);
    }
    pqsets[rootpq].insert(i);
    if (rssets.find(rootrs) == rssets.end()) {
      rssets[rootrs] = set<int>();
      rssets[rootrs].insert(rootrs);
    }
    rssets[rootrs].insert(i);
  }
  vector<int> num(N + 1, 0);
  for (int i = 1; i <= N; i++) {
    if (num[i] == 0) {
      int rootpq = find(parentpq, i);
      int rootrs = find(parentrs, i);
      set<int> pqset = pqsets[rootpq];
      set<int> rsset = rssets[rootrs];
      set<int> unionset;
      if (pqset.size() < rsset.size()) {
        for (set<int>::iterator iter = pqset.begin(); iter != pqset.end();
             iter++) {
          if (rsset.find(*iter) != rsset.end()) {
            unionset.insert(*iter);
          }
        }
      } else {
        for (set<int>::iterator iter = rsset.begin(); iter != rsset.end();
             iter++) {
          if (pqset.find(*iter) != pqset.end()) {
            unionset.insert(*iter);
          }
        }
      }
      for (set<int>::iterator iter = unionset.begin(); iter != unionset.end();
           iter++) {
        num[*iter] = unionset.size();
      }
    }
    cout << num[i];
    if (i <= (N - 1)) {
      cout << ' ';
    }
  }

  return 0;
}


Fixed submission:
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <map>
#include <set>
#include <utility>
#include <vector>
using namespace std;
int find(vector<int> &parent, int x) {
  if (parent[x] == x) {
    return x;
  } else {
    return (parent[x] = find(parent, parent[x]));
  }
}

void unite(vector<int> &parent, vector<int> &rank, int x, int y) {
  x = find(parent, x);
  y = find(parent, y);
  if (x == y)
    return;
  if (rank[x] < rank[y]) {
    parent[x] = y;
  } else {
    parent[y] = x;
    if (rank[x] == rank[y]) {
      rank[x]++;
    }
  }
}

bool same(vector<int> &parent, int x, int y) {
  return find(parent, x) == find(parent, y);
}

int main() {
  int N;
  int K, L;
  scanf("%d%d%d", &N, &K, &L);
  vector<pair<int, int>> pq;
  vector<pair<int, int>> rs;
  for (int i = 0; i < K; i++) {
    pair<int, int> temppq;
    scanf("%d%d", &(temppq.first), &(temppq.second));
    pq.push_back(temppq);
  }
  for (int i = 0; i < L; i++) {
    pair<int, int> temprs;
    scanf("%d%d", &(temprs.first), &(temprs.second));
    rs.push_back(temprs);
  }
  vector<int> parentpq(N + 1, 0);
  vector<int> rankpq(N + 1, 0);
  for (int i = 1; i <= N; i++) {
    parentpq[i] = i;
    rankpq[i] = 0;
  }
  vector<int> parentrs(N + 1, 0);
  vector<int> rankrs(N + 1, 0);
  for (int i = 1; i <= N; i++) {
    parentrs[i] = i;
    rankrs[i] = 0;
  }
  for (int i = 0; i < K; i++) {
    unite(parentpq, rankpq, pq[i].first, pq[i].second);
  }
  for (int i = 0; i < L; i++) {
    unite(parentrs, rankrs, rs[i].first, rs[i].second);
  }
  map<int, set<int>> pqsets;
  map<int, set<int>> rssets;
  for (int i = 1; i <= N; i++) {
    int rootpq = find(parentpq, i);
    int rootrs = find(parentrs, i);
    if (pqsets.find(rootpq) == pqsets.end()) {
      pqsets[rootpq] = set<int>();
      pqsets[rootpq].insert(rootpq);
    }
    pqsets[rootpq].insert(i);
    if (rssets.find(rootrs) == rssets.end()) {
      rssets[rootrs] = set<int>();
      rssets[rootrs].insert(rootrs);
    }
    rssets[rootrs].insert(i);
  }
  vector<int> num(N + 1, 0);
  for (int i = 1; i <= N; i++) {
    if (num[i] == 0) {
      int rootpq = find(parentpq, i);
      int rootrs = find(parentrs, i);
      set<int> &pqset = pqsets[rootpq];
      set<int> &rsset = rssets[rootrs];
      set<int> unionset;
      if (pqset.size() < rsset.size()) {
        for (set<int>::iterator iter = pqset.begin(); iter != pqset.end();
             iter++) {
          if (rsset.find(*iter) != rsset.end()) {
            unionset.insert(*iter);
          }
        }
      } else {
        for (set<int>::iterator iter = rsset.begin(); iter != rsset.end();
             iter++) {
          if (pqset.find(*iter) != pqset.end()) {
            unionset.insert(*iter);
          }
        }
      }
      for (set<int>::iterator iter = unionset.begin(); iter != unionset.end();
           iter++) {
        num[*iter] = unionset.size();
      }
    }
    cout << num[i];
    if (i <= (N - 1)) {
      cout << ' ';
    }
  }

  return 0;
}