Problem p03045 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <limits>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
#define rep(i, a) for (int i = (int)0; i < (int)a; ++i)
#define pb push_back
#define eb emplace_back
#define mp make_pair
#define fi first
#define se second
using ll = long long;
static const ll mod = 1e9 + 7;
static const ll INF = 1LL << 50;
using namespace std;

struct UF {
  vector<int> par;  // 親
  vector<int> Rank; // 木の深さ

  UF(int n) { init(n); }

  // 初期化
  void init(int n) {
    par.resize(n);
    Rank.resize(n);
    for (int i = 0; i < n; i++) {
      par[i] = i;
      Rank[i] = 0;
    }
  }

  // 木の根を求める
  int find(int x) {
    if (par[x] == x) {
      return x;
    } else {
      return par[x] = find(par[x]);
    }
  }

  // xとyの属する集合を併合
  void unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y)
      return; // すでに同じ集合に属している

    if (Rank[x] < Rank[y]) { // 高さが小さい方を下に
      par[x] = y;
    } else {
      par[y] = x;
      if (Rank[x] == Rank[y])
        Rank[x]++; // 同じだとrankが変わらないままになるので増やす（それ以外は大きい方のrankが採用される）
    }
  }

  // xとyが同じ集合に属するかを判定
  bool same(int x, int y) { return find(x) == find(y); }
};

int main() {
  ll n, m;
  cin >> n >> m;
  vector<ll> x(n), y(n), z(n);
  rep(i, m) {
    cin >> x[i] >> y[i] >> z[i];
    x[i]--;
    y[i]--;
  }
  struct UF tree(n + 1);
  rep(i, m) { tree.unite(x[i], y[i]); }
  map<int, ll> s;
  for (int i = 0; i < n; ++i) {
    s[tree.find(i)]++;
  }
  cout << s.size() << endl;
}

Fixed submission:
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <limits>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
#define rep(i, a) for (int i = (int)0; i < (int)a; ++i)
#define pb push_back
#define eb emplace_back
#define mp make_pair
#define fi first
#define se second
using ll = long long;
static const ll mod = 1e9 + 7;
static const ll INF = 1LL << 50;
using namespace std;

struct UF {
  vector<int> par;  // 親
  vector<int> Rank; // 木の深さ

  UF(int n) { init(n); }

  // 初期化
  void init(int n) {
    par.resize(n);
    Rank.resize(n);
    for (int i = 0; i < n; i++) {
      par[i] = i;
      Rank[i] = 0;
    }
  }

  // 木の根を求める
  int find(int x) {
    if (par[x] == x) {
      return x;
    } else {
      return par[x] = find(par[x]);
    }
  }

  // xとyの属する集合を併合
  void unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y)
      return; // すでに同じ集合に属している

    if (Rank[x] < Rank[y]) { // 高さが小さい方を下に
      par[x] = y;
    } else {
      par[y] = x;
      if (Rank[x] == Rank[y])
        Rank[x]++; // 同じだとrankが変わらないままになるので増やす（それ以外は大きい方のrankが採用される）
    }
  }

  // xとyが同じ集合に属するかを判定
  bool same(int x, int y) { return find(x) == find(y); }
};

int main() {
  ll n, m;
  cin >> n >> m;
  vector<ll> x(m), y(m), z(m);
  rep(i, m) {
    cin >> x[i] >> y[i] >> z[i];
    x[i]--;
    y[i]--;
  }
  struct UF tree(n + 1);
  rep(i, m) { tree.unite(x[i], y[i]); }
  map<int, ll> s;
  for (int i = 0; i < n; ++i) {
    s[tree.find(i)]++;
  }
  cout << s.size() << endl;
}