Problem p02536 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vl;
#define REP(i, n) for (int i = 0, i##_len = (n); i < i##_len; ++i)
#define FOR(i, a, b) for (int i = (a), i##_len = (b); i < i##_len; i++)
#define ALL(x) (x).begin(), (x).end() // sortなどの引数を省略したい
#ifdef _DEBUG
#define PRE_COMMAND                                                            \
  std::cin.rdbuf(in.rdbuf());                                                  \
  std::cout << fixed << setprecision(15);
#else
#define PRE_COMMAND cout << fixed << setprecision(15);
#endif
const double EPS = 1e-10, PI = acos(-1.0);
template <class T> auto MAX(T &seq) {
  return *max_element(seq.begin(), seq.end());
}
template <class T> auto MIN(T &seq) {
  return *min_element(seq.begin(), seq.end());
}
template <class T> auto SUM(T &seq) {
  T temp{0};
  auto &temp2 = temp[0];
  return accumulate(seq.begin(), seq.end(), temp2);
}
template <class T> void SORT(T &seq) { sort(seq.begin(), seq.end()); }
template <class T, class S> void SORT(T &seq, S &sort_order) {
  sort(seq.begin(), seq.end(), sort_order);
}
template <class T> void SORTR(vector<T> &seq) {
  sort(seq.begin(), seq.end(), greater<T>());
}
template <class T, class S, class R> long long pow(T n_0, S k_0, R mod_0) {
  long long n = n_0 % mod_0, k = k_0, mod = mod_0, now = 1;
  while (k) {
    if (k & 1)
      now = (now * n) % mod;
    n = (n * n) % mod;
    k >>= 1;
  }
  return now;
}
template <typename T> istream &operator>>(istream &is, vector<T> &vec) {
  for (T &x : vec)
    is >> x;
  return is;
}

int main() {
  PRE_COMMAND
  int n, m, a, b;
  cin >> n >> m;
  struct unionfind { // size:要素数,tree：unionfind木
    int n;
    vector<int> tree_leader, tree_size;
    unionfind(int temp) : n(temp) {
      tree_leader.assign(n, 0);
      tree_size.assign(n, 1);
      for (int i = 0; i < n; i++) {
        tree_leader[i] = i;
      }
    }
    // 結合
    void merge(int index1, int index2) {
      int l1 = leader(index1), l2 = leader(index2);
      if (l1 != l2) {
        if (tree_size[l1] <= tree_size[l2]) {
          tree_leader[l1] = l2;
          tree_size[l2] = tree_size[l1] + tree_size[l2];
        } else {
          tree_leader[l2] = l1;
          tree_size[l1] = tree_size[l1] + tree_size[l2];
        }
      }
    }
    // 同じか判定
    bool same(int index1, int index2) {
      return leader(index1) == leader(index2);
    }
    // leaderを探す
    int leader(int index) {
      vector<int> temp_list(0);
      int temp = tree_leader[index];
      while (index != temp) {
        temp_list.push_back(index);
        index = temp;
        temp = tree_leader[index];
      }
      for (int i : temp_list) {
        tree_leader[i] = index;
      }
      return index;
    }
    // 連結成分のサイズ
    int size(int index) { return tree_size[leader(index)]; }
    // 「一つの連結成分の頂点番号のリスト」のリスト
    vector<vector<int>> groups() {
      int cnt = -1;
      vector<int> id_list(n, -1);
      vector<vector<int>> ret;
      for (int i = 0; i < n; i++) {
        int l = leader(i);
        if (id_list[l] == -1) {
          id_list[l] = ++cnt;
          ret.push_back({i});
        } else {
          ret[id_list[l]].push_back(i);
        }
      }
      return ret;
    }
    // 連結成分の個数
    int component() { return (int)groups().size(); }
  };
  unionfind uf(n);
  REP(i, m) {
    cin >> a >> b;
    uf.merge(a, b);
  }
  cout << uf.component() - 1 << endl;
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vl;
#define REP(i, n) for (int i = 0, i##_len = (n); i < i##_len; ++i)
#define FOR(i, a, b) for (int i = (a), i##_len = (b); i < i##_len; i++)
#define ALL(x) (x).begin(), (x).end() // sortなどの引数を省略したい
#ifdef _DEBUG
#define PRE_COMMAND                                                            \
  std::cin.rdbuf(in.rdbuf());                                                  \
  std::cout << fixed << setprecision(15);
#else
#define PRE_COMMAND cout << fixed << setprecision(15);
#endif
const double EPS = 1e-10, PI = acos(-1.0);
template <class T> auto MAX(T &seq) {
  return *max_element(seq.begin(), seq.end());
}
template <class T> auto MIN(T &seq) {
  return *min_element(seq.begin(), seq.end());
}
template <class T> auto SUM(T &seq) {
  T temp{0};
  auto &temp2 = temp[0];
  return accumulate(seq.begin(), seq.end(), temp2);
}
template <class T> void SORT(T &seq) { sort(seq.begin(), seq.end()); }
template <class T, class S> void SORT(T &seq, S &sort_order) {
  sort(seq.begin(), seq.end(), sort_order);
}
template <class T> void SORTR(vector<T> &seq) {
  sort(seq.begin(), seq.end(), greater<T>());
}
template <class T, class S, class R> long long pow(T n_0, S k_0, R mod_0) {
  long long n = n_0 % mod_0, k = k_0, mod = mod_0, now = 1;
  while (k) {
    if (k & 1)
      now = (now * n) % mod;
    n = (n * n) % mod;
    k >>= 1;
  }
  return now;
}
template <typename T> istream &operator>>(istream &is, vector<T> &vec) {
  for (T &x : vec)
    is >> x;
  return is;
}

int main() {
  PRE_COMMAND
  int n, m, a, b;
  cin >> n >> m;
  struct unionfind { // size:要素数,tree：unionfind木
    int n;
    vector<int> tree_leader, tree_size;
    unionfind(int temp) : n(temp) {
      tree_leader.assign(n, 0);
      tree_size.assign(n, 1);
      for (int i = 0; i < n; i++) {
        tree_leader[i] = i;
      }
    }
    // 結合
    void merge(int index1, int index2) {
      int l1 = leader(index1), l2 = leader(index2);
      if (l1 != l2) {
        if (tree_size[l1] <= tree_size[l2]) {
          tree_leader[l1] = l2;
          tree_size[l2] = tree_size[l1] + tree_size[l2];
        } else {
          tree_leader[l2] = l1;
          tree_size[l1] = tree_size[l1] + tree_size[l2];
        }
      }
    }
    // 同じか判定
    bool same(int index1, int index2) {
      return leader(index1) == leader(index2);
    }
    // leaderを探す
    int leader(int index) {
      vector<int> temp_list(0);
      int temp = tree_leader[index];
      while (index != temp) {
        temp_list.push_back(index);
        index = temp;
        temp = tree_leader[index];
      }
      for (int i : temp_list) {
        tree_leader[i] = index;
      }
      return index;
    }
    // 連結成分のサイズ
    int size(int index) { return tree_size[leader(index)]; }
    // 「一つの連結成分の頂点番号のリスト」のリスト
    vector<vector<int>> groups() {
      int cnt = -1;
      vector<int> id_list(n, -1);
      vector<vector<int>> ret;
      for (int i = 0; i < n; i++) {
        int l = leader(i);
        if (id_list[l] == -1) {
          id_list[l] = ++cnt;
          ret.push_back({i});
        } else {
          ret[id_list[l]].push_back(i);
        }
      }
      return ret;
    }
    // 連結成分の個数
    int component() { return (int)groups().size(); }
  };
  unionfind uf(n);
  REP(i, m) {
    cin >> a >> b;
    uf.merge(a - 1, b - 1);
  }
  cout << uf.component() - 1 << endl;
}