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

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
constexpr ll MOD = 1000000007;
#define REP(i, n) for (ll i = 0; i < (n); i++)
#define REP2(i, x, n) for (ll i = x; i < (n); i++)
#define PR(x) cout << (x) << "\\n"
#define PS(x) cout << (x) << " "
const long long INF = numeric_limits<long long>::max();
void dumpVector(const vector<ll> &vec) {
#ifdef SOURCE_TEST
  for (ll i = 0; i < vec.size(); ++i) {
    cout << vec[i] << ",";
  }
  cout << endl;
#endif
}

class UnionFind {
  // 自身が親であれば、その集合に属する頂点数に-1を掛けたもの
  // そうでなければ親のid
public:
  vector<ll> datas;
  UnionFind(ll N) : datas(N, -1) {}
  bool isRoot(ll x) const { return datas[x] < 0; }
  ll root(ll x) {
    if (isRoot(x))
      return x;
    // Rootの情報を更新する
    datas[x] = root(datas[x]);
    return datas[x];
  }

  bool unite(ll x, ll y) {
    x = root(x);
    y = root(y);
    if (x == y)
      return false;
    if (datas[x] > datas[y])
      swap(x, y);
    datas[x] += datas[y];
    datas[y] = x;
    return true;
  }

  ll size(ll x) { return -datas[root(x)]; }

  void Dump() {
#ifdef SOURCE_TEST
    REP(i, datas.size()) {
      if (isRoot(i)) {
        PS("Root:");
        PS(size(i));
      } else {
        cout << datas[i] << ":";
      }

      PR(i);
    }
#endif
  }
};

int main() {
  ll N, M;
  cin >> N >> M;

  UnionFind UF(N);
  for (int i = 0; i < M; i++) {
    int A, B;
    cin >> A >> B;
    A -= 1;
    B -= 1;
    UF.unite(A, B);
  }

  UF.Dump();

  // 最大の友達集合を求める
  ll ans = 0;
  for (int i = 0; i < N; i++) {
    ans = max(ans, UF.size(i));
  }

  cout << ans << endl;
  return 0;
}

Error: 0

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
constexpr ll MOD = 1000000007;
#define REP(i, n) for (ll i = 0; i < (n); i++)
#define REP2(i, x, n) for (ll i = x; i < (n); i++)
#define PR(x) cout << (x) << "\\n"
#define PS(x) cout << (x) << " "
const long long INF = numeric_limits<long long>::max();
void dumpVector(const vector<ll> &vec) {
#ifdef SOURCE_TEST
  for (ll i = 0; i < vec.size(); ++i) {
    cout << vec[i] << ",";
  }
  cout << endl;
#endif
}

class UnionFind {
  // 自身が親であれば、その集合に属する頂点数に-1を掛けたもの
  // そうでなければ親のid
public:
  vector<ll> datas;
  UnionFind(ll N) : datas(N, -1) {}
  bool isRoot(ll x) const { return datas[x] < 0; }
  ll root(ll x) const {
    if (isRoot(x))
      return x;
    return datas[x];
  }

  ll updateRoot(ll x) {
    if (isRoot(x))
      return x;
    // Rootの情報を更新する
    datas[x] = root(datas[x]);
    return datas[x];
  }

  bool unite(ll x, ll y) {
    x = updateRoot(x);
    y = updateRoot(y);
    if (x == y)
      return false;
    if (datas[x] > datas[y])
      swap(x, y);
    datas[x] += datas[y];
    datas[y] = x;
    return true;
  }

  ll size(ll x) const { return -datas[root(x)]; }

  void Dump() const {
#ifdef SOURCE_TEST
    REP(i, datas.size()) {
      if (isRoot(i)) {
        PS("Root:");
        PS(size(i));
      } else {
        cout << datas[i] << ":";
      }

      PR(i);
    }
#endif
  }
};

int main() {
  ll N, M;
  cin >> N >> M;

  UnionFind UF(N);
  for (int i = 0; i < M; i++) {
    int A, B;
    cin >> A >> B;
    A -= 1;
    B -= 1;
    UF.unite(A, B);
  }

  UF.Dump();

  // 最大の友達集合を求める
  ll ans = 0;
  for (int i = 0; i < N; i++) {
    ans = max(ans, UF.size(i));
  }

  cout << ans << endl;
  return 0;
}