Problem p02762 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef vector<ll> vll;
#define all(x) (x).begin(), (x).end()
ll inf = LLONG_MAX;
long double pi = M_PI;
void Yes() { cout << "Yes" << endl; }
void No() { cout << "No" << endl; }
void YES() { cout << "YES" << endl; }
void NO() { cout << "NO" << endl; }

// UnionFind
// 全て添字で扱うこと
struct union_find {
  vll parent;
  vll sizes;

  // 初期化
  void init(ll n) {
    for (ll i = 0; i < n; i++)
      parent.push_back(i);
    for (ll i = 0; i < n; i++)
      sizes.push_back(1);
    return;
  }

  // 頂点nの根
  ll root(ll n) {
    if (parent[n] == n)
      return n;
    return parent[n] = root(parent[n]);
  }

  // 頂点nと間接的に繋がっている頂点の数(自身含む)
  ll size(ll n) { return sizes[root(n)]; }

  // 頂点a, bが間接的に繋がっているか判定
  bool is_united(ll a, ll b) { return (root(a) == root(b)); }

  // 頂点aを含むグラフに頂点bを含むグラフを結合
  void unite(ll a, ll b) {
    if (is_united(a, b))
      return;
    sizes[root(a)] += size(b);
    parent[root(b)] = root(a);
    return;
  }
};

int main() {
  ll n, m, k;
  cin >> n >> m >> k;

  union_find uf;
  uf.init(n);

  vll a(m), b(m), c(m), d(m);
  vector<vll> nx(n);
  for (ll i = 0; i < m; i++) {
    cin >> a[i] >> b[i];
    uf.unite(a[i] - 1, b[i] - 1);
    nx[a[i] - 1].push_back(b[i] - 1);
    nx[b[i] - 1].push_back(a[i] - 1);
  }
  vll cnt(n, 0);
  for (ll i = 0; i < k; i++) {
    cin >> c[i] >> d[i];
    if (uf.is_united(c[i] - 1, d[i] - 1)) {
      cnt[c[i] - 1]++;
      cnt[d[i] - 1]++;
    }
  }

  for (ll i = 0; i < n - 1; i++) {
    cout << uf.size(i) - 1 - nx[i].size() - cnt[i] << " ";
  }
  cout << uf.size(n - 1) - 1 - nx[n - 1].size() - cnt[n - 1] << endl;
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef vector<ll> vll;
#define all(x) (x).begin(), (x).end()
ll inf = LLONG_MAX;
long double pi = M_PI;
void Yes() { cout << "Yes" << endl; }
void No() { cout << "No" << endl; }
void YES() { cout << "YES" << endl; }
void NO() { cout << "NO" << endl; }

// UnionFind
// 全て添字で扱うこと
struct union_find {
  vll parent;
  vll sizes;

  // 初期化
  void init(ll n) {
    for (ll i = 0; i < n; i++)
      parent.push_back(i);
    for (ll i = 0; i < n; i++)
      sizes.push_back(1);
    return;
  }

  // 頂点nの根
  ll root(ll n) {
    if (parent[n] == n)
      return n;
    return parent[n] = root(parent[n]);
  }

  // 頂点nと間接的に繋がっている頂点の数(自身含む)
  ll size(ll n) { return sizes[root(n)]; }

  // 頂点a, bが間接的に繋がっているか判定
  bool is_united(ll a, ll b) { return (root(a) == root(b)); }

  // 頂点aを含むグラフに頂点bを含むグラフを結合
  void unite(ll a, ll b) {
    if (is_united(a, b))
      return;
    sizes[root(a)] += size(b);
    parent[root(b)] = root(a);
    return;
  }
};

int main() {
  ll n, m, k;
  cin >> n >> m >> k;

  union_find uf;
  uf.init(n);

  vll a(m), b(m), c(k), d(k);
  vector<vll> nx(n);
  for (ll i = 0; i < m; i++) {
    cin >> a[i] >> b[i];
    uf.unite(a[i] - 1, b[i] - 1);
    nx[a[i] - 1].push_back(b[i] - 1);
    nx[b[i] - 1].push_back(a[i] - 1);
  }
  vll cnt(n, 0);
  for (ll i = 0; i < k; i++) {
    cin >> c[i] >> d[i];
    if (uf.is_united(c[i] - 1, d[i] - 1)) {
      cnt[c[i] - 1]++;
      cnt[d[i] - 1]++;
    }
  }

  for (ll i = 0; i < n - 1; i++) {
    cout << uf.size(i) - 1 - nx[i].size() - cnt[i] << " ";
  }
  cout << uf.size(n - 1) - 1 - nx[n - 1].size() - cnt[n - 1] << endl;
}