Problem p02573 (C++) — buggy submission, verdict: Runtime Error

#include <bits/stdc++.h>
#define REP(i, n) for (int i = 0; i < (n); ++i)
#define REPR(i, n, m) for (int i = (n); i >= (m); --i)
using namespace std;
using LL = long long;
using LD = long double;
using PLL = pair<long long, long long>;
using PLD = pair<long double, long double>;
using VLL = vector<long long>;
using VLD = vector<long double>;
using VPLL = vector<PLL>;
using VPLD = vector<PLD>;

const int INF = numeric_limits<int>::max();
const unsigned long long int ULLINF =
    numeric_limits<unsigned long long int>::max();

struct UnionFind {
  vector<int> par; // par[i]:iの親の番号　(例) par[3] = 2 : 3の親が2

  UnionFind(int N) : par(N) { // 最初は全てが根であるとして初期化
    for (int i = 0; i < N; i++)
      par[i] = i;
  }

  int root(int x) { // データxが属する木の根を再帰で得る：root(x) = {xの木の根}
    if (par[x] == x)
      return x;
    return par[x] = root(par[x]);
  }

  void unite(int x, int y) { // xとyの木を併合
    int rx = root(x);        // xの根をrx
    int ry = root(y);        // yの根をry
    if (rx == ry)
      return; // xとyの根が同じ(=同じ木にある)時はそのまま
    par[rx] =
        ry; // xとyの根が同じでない(=同じ木にない)時：xの根rxをyの根ryにつける
  }

  bool same(int x, int y) { // 2つのデータx, yが属する木が同じならtrueを返す
    int rx = root(x);
    int ry = root(y);
    return rx == ry;
  }
};

int main() {

  LL n, m;
  cin >> n >> m;

  UnionFind tree(n);

  REP(i, m) {
    LL num1, num2;
    cin >> num1 >> num2;
    tree.unite(num1 - 1, num2 - 1);
  }

  VLL v(n, -1);

  for (LL i = 0; i < n; i++) {
    LL r = tree.root(i);
    if (v[r] == -1)
      v[r] = 1;
    else
      v[r] += 1;
  }

  LL ans = 0;
  for (LL i = 0; i < n; i++) {
    // cout << i+1 <<  ":" << v[i] << endl;
    ans = max(ans, v[i]);
  }

  cout << ans << endl;

  return 0;
}


Error: 0

Fixed submission:

#include <bits/stdc++.h>
#define REP(i, n) for (int i = 0; i < (n); ++i)
#define REPR(i, n, m) for (int i = (n); i >= (m); --i)
using namespace std;
using LL = long long;
using LD = long double;
using PLL = pair<long long, long long>;
using PLD = pair<long double, long double>;
using VLL = vector<long long>;
using VLD = vector<long double>;
using VPLL = vector<PLL>;
using VPLD = vector<PLD>;

const int INF = numeric_limits<int>::max();
const unsigned long long int ULLINF =
    numeric_limits<unsigned long long int>::max();

struct UnionFind {
  vector<int> par; // par[i]:iの親の番号　(例) par[3] = 2 : 3の親が2

  UnionFind(int N) : par(N) { // 最初は全てが根であるとして初期化
    for (int i = 0; i < N; i++)
      par[i] = i;
  }

  int root(int x) { // データxが属する木の根を再帰で得る：root(x) = {xの木の根}
    if (par[x] == x)
      return x;
    return par[x] = root(par[x]);
  }

  void unite(int x, int y) { // xとyの木を併合
    int rx = root(x);        // xの根をrx
    int ry = root(y);        // yの根をry
    if (rx == ry)
      return; // xとyの根が同じ(=同じ木にある)時はそのまま
    par[rx] =
        ry; // xとyの根が同じでない(=同じ木にない)時：xの根rxをyの根ryにつける
  }

  bool same(int x, int y) { // 2つのデータx, yが属する木が同じならtrueを返す
    int rx = root(x);
    int ry = root(y);
    return rx == ry;
  }
};

int main() {

  LL n, m;
  cin >> n >> m;

  UnionFind tree(n);

  REP(i, m) {
    LL num1, num2;
    cin >> num1 >> num2;
    tree.unite(num1 - 1, num2 - 1);
  }

  VLL v(200001, 0);
  LL index_max = 0;

  for (LL i = 1; i <= n; i++) {
    LL r = tree.root(i);
    // cout << "a" << endl;
    index_max = max(index_max, r);
    v[r] += 1;
  }

  LL ans = 0;
  for (LL i = 1; i <= index_max; i++) {
    ans = max(ans, v[i]);
  }

  cout << ans << endl;

  return 0;
}