Problem p02573 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <algorithm>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <vector>
#define rep(i, n) for (int i = 0; i < (int)(n); i++)

using namespace std;
using ll = long long;

template <typename T> using vec2 = vector<vector<T>>;
template <typename T> using vec3 = vec2<vector<T>>;
template <typename T> using vec4 = vec3<vector<T>>;
template <typename T> using vec5 = vec4<vector<T>>;
template <typename T> using vec6 = vec5<vector<T>>;

struct UnionFind {
  vector<int> parents;
  vector<int> sizes;
  int N;

  UnionFind(int N) : N(N) {
    parents = vector<int>(N, -1);
    for (int i = 0; i < N; i++)
      parents[i] = i;
    sizes = vector<int>(N, 1);
  }

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

  bool connect(int a, int b) {
    a = find(a);
    b = find(b);
    if (a == b)
      return false;
    if (sizes[a] <= sizes[b])
      swap(a, b);
    sizes[a] += sizes[b];
    parents[b] = a;
    return true;
  }
  int size(int a) { return sizes[find(a)]; }
};

int main() {
  int N, M;
  cin >> N >> M;
  UnionFind u(N);
  for (int i = 0; i < M; i++) {
    int a, b;
    cin >> a >> b;
    a--;
    b--;
    u.connect(a, b);
  }
  int ans = 0;

  for (int i = 0; i < N; i++) {
    // cout<<u.size(i)<<endl;
    ans = max(ans, u.size(i));
  }
  cout << ans << endl;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <vector>
#define rep(i, n) for (int i = 0; i < (int)(n); i++)

using namespace std;
using ll = long long;

template <typename T> using vec2 = vector<vector<T>>;
template <typename T> using vec3 = vec2<vector<T>>;
template <typename T> using vec4 = vec3<vector<T>>;
template <typename T> using vec5 = vec4<vector<T>>;
template <typename T> using vec6 = vec5<vector<T>>;

struct UnionFind {
  // 親の頂点番号または(木のサイズ+N)
  vector<int> parents;
  vector<int> ranks;
  int N;

  UnionFind(int N) : N(N) {
    parents = vector<int>(N, N + 1);
    ranks = vector<int>(N, 0);
  }

  int find(int a) {
    if (parents[a] >= N)
      return a;
    int root = find(parents[a]);
    parents[a] = root;
    return root;
  }

  bool connect(int a, int b) {
    int root_a = find(a);
    int root_b = find(b);
    if (root_a == root_b)
      return false;
    if (ranks[a] > ranks[b]) {
      parents[root_a] += parents[root_b] - N;
      parents[root_b] = root_a;
    } else if (ranks[a] < ranks[b]) {
      parents[root_b] += parents[root_a] - N;
      parents[root_a] = root_b;
    } else {
      parents[root_b] += parents[root_a] - N;
      parents[root_a] = root_b;
      ranks[root_b]++;
    }
    return true;
  }
  int size(int a) {
    if (parents[a] >= N)
      return parents[a] - N;
    return size(parents[a]);
  }
};

int main() {
  int N, M;
  cin >> N >> M;
  vector<set<ll>> graph(N, set<ll>());
  UnionFind u(N);
  for (int i = 0; i < M; i++) {
    int a, b;
    cin >> a >> b;
    a--;
    b--;
    u.connect(a, b);
  }
  int ans = 0;

  for (int i = 0; i < N; i++) {
    // cout<<u.size(i)<<endl;
    ans = max(ans, u.size(i));
  }
  cout << ans << endl;
}