prithivMLmods/Coder-Stat huggingface dataset:
Problem p03354 (Python)

Buggy submission (status: Runtime Error):
n, m = map(int, input().split())
p = list(map(lambda x: int(x) - 1, input().split()))
xy = [list(map(lambda x: int(x) - 1, input().split())) for _ in range(n)]

par = [i for i in range(n)]
rank = [0 for _ in range(n)]


def root(x):
    if par[x] == x:
        return x
    par[x] = root(par[x])
    return par[x]


def is_same(x, y):
    return root(x) == root(y)


def union(x, y):
    x = root(x)
    y = root(y)
    if x == y:
        return
    if rank[x] < rank[y]:
        par[x] = y
    else:
        par[y] = x
        if rank[x] == rank[y]:
            rank[x] += 1


for x, y in xy:
    union(x, y)

count = 0
for i, p_i in enumerate(p):
    count += 1 if is_same(i, p_i) else 0
print(count)


Fixed submission:
n, m = map(int, input().split())
p = list(map(lambda x: int(x) - 1, input().split()))
xy = [list(map(lambda x: int(x) - 1, input().split())) for _ in range(m)]

par = [i for i in range(n)]
rank = [0 for _ in range(n)]


def root(x):
    if par[x] == x:
        return x
    par[x] = root(par[x])
    return par[x]


def is_same(x, y):
    return root(x) == root(y)


def union(x, y):
    x = root(x)
    y = root(y)
    if x == y:
        return
    if rank[x] < rank[y]:
        par[x] = y
    else:
        par[y] = x
        if rank[x] == rank[y]:
            rank[x] += 1


for x, y in xy:
    union(x, y)

count = 0
for i, p_i in enumerate(p):
    count += 1 if is_same(i, p_i) else 0
print(count)
Problem p03354 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < (n); i++)
#define rep2(i, n) for (int i = 1; i <= (n); i++)
typedef long long ll;

int p[13];
int par[13];

int root(int i) {
  if (par[i] == i)
    return i;
  return par[i] = root(par[i]);
}

void unite(int x, int y) {
  int rx = root(x), ry = root(y);
  if (rx != ry)
    par[rx] = ry;
}

int main() {
  int N, K;
  cin >> N >> K;
  rep2(i, N) {
    cin >> p[i];
    par[i] = i;
  }
  rep(i, K) {
    int a, b;
    cin >> a >> b;
    unite(p[a], p[b]);
  }
  int ans = 0;
  rep2(i, N) {
    if (root(i) == root(p[i]))
      ans++;
  }
  cout << ans << endl;
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < (n); i++)
#define rep2(i, n) for (int i = 1; i <= (n); i++)
typedef long long ll;

int p[100003];
int par[100003];

int root(int i) {
  if (par[i] == i)
    return i;
  return par[i] = root(par[i]);
}

void unite(int x, int y) {
  int rx = root(x), ry = root(y);
  if (rx != ry)
    par[rx] = ry;
}

int main() {
  int N, K;
  cin >> N >> K;
  rep2(i, N) {
    cin >> p[i];
    par[i] = i;
  }
  rep(i, K) {
    int a, b;
    cin >> a >> b;
    unite(p[a], p[b]);
  }
  int ans = 0;
  rep2(i, N) {
    if (root(i) == root(p[i]))
      ans++;
  }
  cout << ans << endl;
}
Problem p03354 (C++)

Buggy submission (status: Runtime Error):
#include <iostream>
#include <vector>
#define MAX_N 10001
using namespace std;

// 要素数はN個
int par[MAX_N];
int ufrank[MAX_N];

void init(int n) {
  for (int i = 0; i < n; ++i) {
    par[i] = i;
    ufrank[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 (ufrank[x] < ufrank[y]) {
    par[x] = y;
  } else {
    par[y] = x;
    if (ufrank[x] == ufrank[y])
      ufrank[x]++;
  }
}

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

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

  vector<int> v(n);
  for (int i = 0; i < n; ++i) {
    cin >> v[i];
  }
  init(n + 1);
  int x, y;
  for (int i = 0; i < m; ++i) {
    cin >> x >> y;
    unite(x, y);
  }
  int ans = 0;
  for (int i = 0; i < n; ++i) {
    if (same(i + 1, v[i])) {
      ++ans;
    }
  }
  cout << ans << endl;
  return 0;
}

Fixed submission:
#include <iostream>
#include <vector>
#define MAX_N 100000
using namespace std;

// 要素数はN個
int par[MAX_N];
int ufrank[MAX_N];

void init(int n) {
  for (int i = 0; i < n; ++i) {
    par[i] = i;
    ufrank[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 (ufrank[x] < ufrank[y]) {
    par[x] = y;
  } else {
    par[y] = x;
    if (ufrank[x] == ufrank[y])
      ufrank[x]++;
  }
}

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

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

  vector<int> v(n);
  for (int i = 0; i < n; ++i) {
    cin >> v[i];
  }
  init(n + 1);
  int x, y;
  for (int i = 0; i < m; ++i) {
    cin >> x >> y;
    unite(x, y);
  }
  int ans = 0;
  for (int i = 0; i < n; ++i) {
    if (same(i + 1, v[i])) {
      ++ans;
    }
  }
  cout << ans << endl;
  return 0;
}
Problem p03354 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <iostream>
#include <math.h>
#include <queue>
#include <vector>
using namespace std;
typedef long long ll;

const int INF = 1001001001;

struct UnionFind {
  vector<int> parent;
  UnionFind(int n) : parent(n) {
    for (int i = 0; i < n; i++)
      parent[i] = i;
  }

  int root(int x) {
    if (parent[x] == x)
      return x;
    return root(parent[x]);
  }

  void unite(int x, int y) {
    int rx = root(x);
    int ry = root(y);
    if (rx == ry)
      return;
    parent[rx] = ry;
  }

  bool same_root(int x, int y) {
    int rx = root(x);
    int ry = root(y);
    return rx == ry;
  }
};

int main() {
  int n, m;
  cin >> n >> m;
  vector<int> p(n);
  for (int i = 0; i < n; i++) {
    cin >> p[i];
    p[i]--;
  }

  UnionFind tree(n);
  for (int i = 0; i < m; i++) {
    int x, y;
    cin >> x >> y;
    x--;
    y--;
    tree.unite(x, y);
  }

  int ans = 0;
  for (int i = 0; i < n; i++) {
    if (tree.same_root(i, p[i]))
      ans++;
  }
  cout << ans << endl;

  return 0;
}

Fixed submission:
#include <algorithm>
#include <iostream>
#include <math.h>
#include <queue>
#include <vector>
using namespace std;
typedef long long ll;

const int INF = 1001001001;

struct UnionFind {
  vector<int> parent;
  UnionFind(int n) : parent(n) {
    for (int i = 0; i < n; i++)
      parent[i] = i;
  }

  int root(int x) {
    if (parent[x] == x)
      return x;
    return parent[x] = root(parent[x]);
  }

  void unite(int x, int y) {
    int rx = root(x);
    int ry = root(y);
    if (rx == ry)
      return;
    parent[rx] = ry;
  }

  bool same_root(int x, int y) {
    int rx = root(x);
    int ry = root(y);
    return rx == ry;
  }
};

int main() {
  int n, m;
  cin >> n >> m;
  vector<int> p(n);
  for (int i = 0; i < n; i++) {
    cin >> p[i];
    p[i]--;
  }

  UnionFind tree(n);
  for (int i = 0; i < m; i++) {
    int x, y;
    cin >> x >> y;
    x--;
    y--;
    tree.unite(x, y);
  }

  int ans = 0;
  for (int i = 0; i < n; i++) {
    if (tree.same_root(i, p[i]))
      ans++;
  }
  cout << ans << endl;

  return 0;
}
Problem p03354 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;

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() {
  int N, M;

  cin >> N >> M;
  vector<int> P(N);
  for (int i = 0; i < N; i++) {
    cin >> P[i];
  }

  UnionFind tree(N);

  for (int i = 0; i < M; i++) {
    int x, y;
    cin >> x >> y;
    tree.unite(x - 1, y - 1); // x-1の木とy-1の木を併合する
  }

  int count = 0;
  for (int i = 0; i < N; i++) {
    if (P[i] == i + 1)
      count++;
    else if (tree.same(P[i], i))
      count++;
  }

  cout << count;
}


Fixed submission:
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;

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() {
  int N, M;

  cin >> N >> M;
  vector<int> P(N);
  for (int i = 0; i < N; i++) {
    cin >> P[i];
  }

  UnionFind tree(N);

  for (int i = 0; i < M; i++) {
    int x, y;
    cin >> x >> y;
    tree.unite(x - 1, y - 1); // x-1の木とy-1の木を併合する
  }

  int count = 0;
  for (int i = 0; i < N; i++) {
    if (tree.same(P[i] - 1, i))
      count++;
  }

  cout << count;
}
Problem p03354 (C++)

Buggy submission (status: Runtime Error):
/**
 *    author:  FromDihPout
 *    created: 2020-08-16
 **/

#include <bits/stdc++.h>
using namespace std;

int dfs(int u, set<int> &comp, vector<vector<int>> &adj) {
  comp.insert(u);
  for (int v : adj[u]) {
    if (comp.count(v))
      continue;
    dfs(v, comp, adj);
  }
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);

  int n, m;
  cin >> n >> m;
  vector<int> p(n + 1);
  for (int i = 1; i <= n; i++) {
    cin >> p[i];
  }
  vector<vector<int>> adj(n + 1);
  for (int i = 0; i < m; i++) {
    int x, y;
    cin >> x >> y;
    adj[x].push_back(y);
    adj[y].push_back(x);
  }

  vector<bool> seen(n + 1);
  set<int> comp;
  int ans = 0;
  for (int i = 1; i <= n; i++) {
    if (seen[i])
      continue;
    comp.clear();
    dfs(i, comp, adj);
    for (int x : comp) {
      if (comp.count(p[x]))
        ans++;
      seen[x] = true;
    }
  }

  for (int i = 1; i <= n; i++) {
    if (!seen[i] && p[i] == i)
      ans++;
  }
  cout << ans << '\n';
  return 0;
}

Fixed submission:
/**
 *    author:  FromDihPout
 *    created: 2020-08-16
 **/

#include <bits/stdc++.h>
using namespace std;

void dfs(int u, set<int> &comp, vector<vector<int>> &adj) {
  comp.insert(u);
  for (int v : adj[u]) {
    if (comp.count(v))
      continue;
    dfs(v, comp, adj);
  }
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);

  int n, m;
  cin >> n >> m;
  vector<int> p(n + 1);
  for (int i = 1; i <= n; i++) {
    cin >> p[i];
  }
  vector<vector<int>> adj(n + 1);
  for (int i = 0; i < m; i++) {
    int x, y;
    cin >> x >> y;
    adj[x].push_back(y);
    adj[y].push_back(x);
  }

  vector<bool> seen(n + 1);
  set<int> comp;
  int ans = 0;
  for (int i = 1; i <= n; i++) {
    if (seen[i])
      continue;
    comp.clear();
    dfs(i, comp, adj);
    for (int x : comp) {
      if (comp.count(p[x]))
        ans++;
      seen[x] = true;
    }
  }

  for (int i = 1; i <= n; i++) {
    if (!seen[i] && p[i] == i)
      ans++;
  }
  cout << ans << '\n';
  return 0;
}
Problem p03354 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
using namespace std;
#define rep(i, j, n) for (int i = (int)(j); i < (int)(n); i++)
#define REP(i, j, n) for (int i = (int)(j); i <= (int)(n); i++)
#define MOD 1000000007
#define int long long
#define ALL(a) (a).begin(), (a).end()
#define vi vector<int>
#define vii vector<vi>
#define pii pair<int, int>
#define priq priority_queue<int>
#define disup(A, key) distance(A.begin(), upper_bound(ALL(A), (int)(key)))
#define dislow(A, key) distance(A.begin(), lower_bound(ALL(A), (int)(key)))
#define tii tuple<int, int, int>
#define Priq priority_queue<int, vi, greater<int>>
#define pb push_back
#define mp make_pair
#define INF (1ll << 60)
signed main() {
  int N, M;
  cin >> N >> M;
  vii A(N);
  vi B(N);
  rep(i, 0, N) cin >> B[i];
  rep(i, 0, M) {
    int X, Y;
    cin >> X >> Y;
    A[X - 1].pb(Y - 1);
    A[Y - 1].pb(X - 1);
  }
  int ans = 0;
  vector<bool> F(N, 1);
  rep(i, 0, N) {
    if (F[i]) {
      F[i] = 0;
      queue<int> Q;
      Q.push(i);
      set<int> S, T;
      S.insert(i);
      T.insert(B[i] - 1);
      while (Q.size() > 0) {
        int K = Q.front();
        rep(j, 0, A[K].size()) {
          int P = A[K][j];
          if (F[P]) {
            Q.push(P);
            F[P] = 0;
            S.insert(P);
            T.insert(B[P] - 1);
          }
        }
      }
      for (auto p : S) {
        if (T.count(p))
          ans++;
      }
    }
  }
  cout << ans << endl;
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;
#define rep(i, j, n) for (int i = (int)(j); i < (int)(n); i++)
#define REP(i, j, n) for (int i = (int)(j); i <= (int)(n); i++)
#define MOD 1000000007
#define int long long
#define ALL(a) (a).begin(), (a).end()
#define vi vector<int>
#define vii vector<vi>
#define pii pair<int, int>
#define priq priority_queue<int>
#define disup(A, key) distance(A.begin(), upper_bound(ALL(A), (int)(key)))
#define dislow(A, key) distance(A.begin(), lower_bound(ALL(A), (int)(key)))
#define tii tuple<int, int, int>
#define Priq priority_queue<int, vi, greater<int>>
#define pb push_back
#define mp make_pair
#define INF (1ll << 60)
signed main() {
  int N, M;
  cin >> N >> M;
  vii A(N);
  vi B(N);
  rep(i, 0, N) cin >> B[i];
  rep(i, 0, M) {
    int X, Y;
    cin >> X >> Y;
    A[X - 1].pb(Y - 1);
    A[Y - 1].pb(X - 1);
  }
  int ans = 0;
  vector<bool> F(N, 1);
  rep(i, 0, N) {
    if (F[i]) {
      F[i] = 0;
      queue<int> Q;
      Q.push(i);
      set<int> S, T;
      S.insert(i);
      T.insert(B[i] - 1);
      while (Q.size() > 0) {
        int K = Q.front();
        Q.pop();
        rep(j, 0, A[K].size()) {
          int P = A[K][j];
          if (F[P]) {
            Q.push(P);
            F[P] = 0;
            S.insert(P);
            T.insert(B[P] - 1);
          }
        }
      }
      for (auto p : S) {
        if (T.count(p))
          ans++;
      }
    }
  }
  cout << ans << endl;
}
Problem p03354 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;

int par[1000000];

void init(int n) {

  for (int i = 1; i <= n; i = i + 1) {

    par[i] = i;
  }

  return;
}

int root(int x) {

  if (par[x] == x)
    return x;

  else
    return par[x] = root(par[x]);
}

bool same(int x, int y) { return root(x) == root(y); }

void unite(int x, int y) {

  x = root(x);

  y = root(y);

  if (x == y)
    return;

  par[x] = y;

  return;
}

int main() {

  int n, m, i, x, y;

  int k = 0;

  cin >> n >> m;

  vector<int> p(10001);

  for (i = 1; i <= n; i = i + 1) {

    cin >> p.at(i);
  }

  init(n);

  for (i = 1; i <= m; i = i + 1) {

    cin >> x >> y;

    unite(p.at(x), p.at(y));
  }

  for (i = 1; i <= n; i = i + 1) {

    if (same(i, p.at(i)))
      k += 1;
  }

  cout << k << endl;

  return 0;
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;

int par[1000000];

void init(int n) {

  for (int i = 1; i <= n; i = i + 1) {

    par[i] = i;
  }

  return;
}

int root(int x) {

  if (par[x] == x)
    return x;

  else
    return par[x] = root(par[x]);
}

bool same(int x, int y) { return root(x) == root(y); }

void unite(int x, int y) {

  x = root(x);

  y = root(y);

  if (x == y)
    return;

  par[x] = y;

  return;
}

int main() {

  int n, m, i, x, y;

  int k = 0;

  cin >> n >> m;

  vector<int> p(100001);

  for (i = 1; i <= n; i = i + 1) {

    cin >> p.at(i);
  }

  init(n);

  for (i = 1; i <= m; i = i + 1) {

    cin >> x >> y;

    unite(p.at(x), p.at(y));
  }

  for (i = 1; i <= n; i = i + 1) {

    if (same(i, p.at(i)))
      k += 1;
  }

  cout << k << endl;

  return 0;
}
Problem p03354 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;

struct UnionFind {
  vector<int> par;
  UnionFind(int N) : par(N) {
    for (int i = 0; i < N; i++)
      par[i] = i;
  }
  int root(int x) {
    if (par[x] == x)
      return x;
    return par[x] = root(par[x]);
  }
  void unite(int x, int y) {
    int rx = root(x);
    int ry = root(y);
    if (rx == ry)
      return;
    par[rx] = ry;
  }

  bool same(int x, int y) {
    int rx = root(x);
    int ry = root(y);
    return rx == ry;
  }
};

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

  vector<int> p(N);
  for (int i = 0; i < N; ++i) {
    cin >> p.at(i);
  }

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

  int sum = 0;
  for (int i = 0; i < N; ++i) {
    if (UF.same(i, p.at(i))) {
      ++sum;
    }
  }

  cout << sum << endl;
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;

struct UnionFind {
  vector<int> par;
  UnionFind(int N) : par(N) {
    for (int i = 0; i < N; i++)
      par[i] = i;
  }
  int root(int x) {
    if (par[x] == x)
      return x;
    return par[x] = root(par[x]);
  }
  void unite(int x, int y) {
    int rx = root(x);
    int ry = root(y);
    if (rx == ry)
      return;
    par[rx] = ry;
  }

  bool same(int x, int y) {
    int rx = root(x);
    int ry = root(y);
    return rx == ry;
  }
};

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

  vector<int> p(N);
  for (int i = 0; i < N; ++i) {
    cin >> p.at(i);
  }

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

  int sum = 0;
  for (int i = 0; i < N; ++i) {
    if (UF.same(i, p.at(i) - 1)) {
      ++sum;
    }
  }

  cout << sum << endl;
}
Problem p03354 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <iostream>

#include <set>
using namespace std;
int n, m;
int x, y;
int p[108000];
set<int> nums[108000];
int ans;
int u[108000];
int r(int x) {
  if (u[x] == x)
    return x;
  return u[x] = r(u[x]);
}

int unite(int x, int y) {
  x = r(x);
  y = r(y);
  u[x] = y;
}

int main() {
  for (int i = 0; i < 10800; i++)
    u[i] = i;
  cin >> n >> m;
  for (int i = 0; i < n; i++)
    cin >> p[i], p[i]--;
  for (int i = 0; i < m; i++) {
    cin >> x >> y;
    x--, y--;
    unite(x, y);
  }

  for (int i = 0; i < n; i++) {
    nums[r(i)].insert(i);
  }

  for (int i = 0; i < n; i++) {
    set<int>::iterator it;
    for (it = nums[i].begin(); it != nums[i].end(); it++) {
      if (nums[i].count(p[*it]))
        ans++;
    }
  }
  cout << ans << endl;
  return 0;
}

Fixed submission:
#include <algorithm>
#include <iostream>

#include <set>
using namespace std;
int n, m;
int x, y;
int p[108000];
set<int> nums[108000];
int ans;
int u[108000];
int r(int x) {
  if (u[x] == x)
    return x;
  return u[x] = r(u[x]);
}

int unite(int x, int y) {
  x = r(x);
  y = r(y);
  u[x] = y;
}

int main() {
  for (int i = 0; i < 108000; i++)
    u[i] = i;
  cin >> n >> m;
  for (int i = 0; i < n; i++)
    cin >> p[i], p[i]--;
  for (int i = 0; i < m; i++) {
    cin >> x >> y;
    x--, y--;
    unite(x, y);
  }

  for (int i = 0; i < n; i++) {
    nums[r(i)].insert(i);
  }

  for (int i = 0; i < n; i++) {
    set<int>::iterator it;
    for (it = nums[i].begin(); it != nums[i].end(); it++) {
      if (nums[i].count(p[*it]))
        ans++;
    }
  }
  cout << ans << endl;
  return 0;
}
Problem p03354 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cstdio>
#include <iostream>
#include <string>
#include <vector>
#define REP(i, n) for (int i = 0; i < n; ++i)
using namespace std;

// UNION FIND
struct UnionFind {
  vector<int> par;
  vector<int> rank;

  // n要素で初期化
  UnionFind(int n) : par(n), rank(n) {
    for (int i = 0; i < n; ++i) {
      par[i] = i;
      rank[i] = 0;
    }
  }

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

  // xとyの属する集合を併合
  void unite(int x, int y) {
    x = root(x);
    y = root(y);
    if (x == y)
      return;
    if (rank[x] < rank[y]) {
      par[x] = y;
    } else {
      par[y] = x;
      if (rank[x] == rank[y])
        ++rank[x];
    }
  }

  bool same(int x, int y) {
    int rx = root(x);
    int ry = root(y);
    return rx == ry;
  }
};

int main() {
  ios::sync_with_stdio(false);
  int N, M;
  cin >> N >> M;
  int p[110000], x[110000], y[110000];
  REP(i, N) cin >> p[i];
  REP(i, M) cin >> x[i] >> y[i];
  UnionFind tree(N);
  REP(i, N) tree.unite(x[i] - 1, y[i] - 1);
  int ans = 0;
  REP(i, N) {
    if (tree.same(i, p[i] - 1))
      ++ans;
  }
  cout << ans << endl;
  return 0;
}

Fixed submission:
#include <algorithm>
#include <cstdio>
#include <iostream>
#include <string>
#include <vector>
#define REP(i, n) for (int i = 0; i < n; ++i)
using namespace std;

// UNION FIND
struct UnionFind {
  vector<int> par;
  vector<int> rank;

  // n要素で初期化
  UnionFind(int n) : par(n), rank(n) {
    for (int i = 0; i < n; ++i) {
      par[i] = i;
      rank[i] = 0;
    }
  }

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

  // xとyの属する集合を併合
  void unite(int x, int y) {
    x = root(x);
    y = root(y);
    if (x == y)
      return;
    if (rank[x] < rank[y]) {
      par[x] = y;
    } else {
      par[y] = x;
      if (rank[x] == rank[y])
        ++rank[x];
    }
  }

  bool same(int x, int y) {
    int rx = root(x);
    int ry = root(y);
    return rx == ry;
  }
};

int main() {
  ios::sync_with_stdio(false);
  int N, M;
  cin >> N >> M;
  int p[110000], x[110000], y[110000];
  REP(i, N) cin >> p[i];
  REP(i, M) cin >> x[i] >> y[i];
  UnionFind tree(N);
  REP(i, M) tree.unite(x[i] - 1, y[i] - 1);
  int ans = 0;
  REP(i, N) {
    if (tree.same(i, p[i] - 1))
      ++ans;
  }
  cout << ans << endl;
  return 0;
}
Problem p03354 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <vector>
using namespace std;

int n, m;
int p[111111];
vector<int> e[111111];

struct DisjointSet {

  vector<int> rank, p;

  DisjointSet() {}
  DisjointSet(int size) {
    rank.resize(size, 0);
    p.resize(size, 0);
    for (int i = 0; i < size; i++)
      makeSet(i);
  }

  void makeSet(int x) {
    p[x] = x;
    rank[x] = 0;
  }

  bool same(int x, int y) { return findSet(x) == findSet(y); }

  void unite(int x, int y) { link(findSet(x), findSet(y)); }

  void link(int x, int y) {
    if (rank[x] > rank[y]) {
      p[y] = x;
    } else {
      p[x] = y;
      if (rank[x] == rank[y]) {
        rank[y]++;
      }
    }
  }

  int findSet(int x) {
    if (x != p[x]) {
      p[x] = findSet(p[x]);
    }
    return p[x];
  }
};

int main() {
  ios_base::sync_with_stdio(false);

  int ans = 0;

  cin >> n >> m;
  for (int i = 1; i <= n; i++) {
    int num;
    cin >> num;
    p[num] = i;
  }

  DisjointSet ds = DisjointSet(n);
  for (int i = 0; i < m; i++) {
    int x, y;
    cin >> x >> y;
    ds.unite(x, y);
  }

  for (int i = 1; i <= n; i++) {
    if (ds.same(p[i], i))
      ans++;
  }

  cout << ans << endl;

  return 0;
}


Fixed submission:
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <vector>
using namespace std;

int n, m;
int p[111111];
vector<int> e[111111];

struct DisjointSet {

  vector<int> rank, p;

  DisjointSet() {}
  DisjointSet(int size) {
    rank.resize(size, 0);
    p.resize(size, 0);
    for (int i = 0; i < size; i++)
      makeSet(i);
  }

  void makeSet(int x) {
    p[x] = x;
    rank[x] = 0;
  }

  bool same(int x, int y) { return findSet(x) == findSet(y); }

  void unite(int x, int y) { link(findSet(x), findSet(y)); }

  void link(int x, int y) {
    if (rank[x] > rank[y]) {
      p[y] = x;
    } else {
      p[x] = y;
      if (rank[x] == rank[y]) {
        rank[y]++;
      }
    }
  }

  int findSet(int x) {
    if (x != p[x]) {
      p[x] = findSet(p[x]);
    }
    return p[x];
  }
};

int main() {
  ios_base::sync_with_stdio(false);

  int ans = 0;

  cin >> n >> m;
  for (int i = 1; i <= n; i++) {
    int num;
    cin >> num;
    p[num] = i;
  }

  DisjointSet ds = DisjointSet(n + 10);
  for (int i = 0; i < m; i++) {
    int x, y;
    cin >> x >> y;
    ds.unite(x, y);
  }

  for (int i = 1; i <= n; i++) {
    if (ds.same(p[i], i))
      ans++;
  }

  cout << ans << endl;

  return 0;
}
Problem p03354 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <iostream>
#include <string.h>
#include <vector>
using namespace std;

int P[100001];

int root(int i) {
  if (P[i] == i) {
    return i;
  }
  return root(P[i]);
}

void unite(int i, int j) {
  // iにjをくっつける
  P[root(j)] = root(i);
}

int main() {
  int n, m;
  cin >> n >> m;
  for (int i = 0; i <= n; i++) {
    P[i] = i;
  }
  int p[n + 1];
  p[0] = 0;
  for (int i = 0; i < n; i++) {
    cin >> p[i + 1];
  }
  for (int i = 0; i < m; i++) {
    int s, ss;
    cin >> s >> ss;
    unite(s, ss);
  }
  int ans = 0;
  for (int i = 1; i <= n; i++) {
    if (root(i) == root(p[i])) {
      ans++;
    }
  }
  cout << ans << endl;
}

Fixed submission:
#include <iostream>
#include <string.h>
#include <vector>
using namespace std;

int P[100001];

int root(int i) {
  if (P[i] == i) {
    return i;
  }
  P[i] = root(P[i]);
  return P[i];
}

void unite(int i, int j) {
  // iにjをくっつける
  P[root(j)] = root(i);
}

int main() {
  int n, m;
  cin >> n >> m;
  for (int i = 0; i <= n; i++) {
    P[i] = i;
  }
  int p[n + 1];
  p[0] = 0;
  for (int i = 0; i < n; i++) {
    cin >> p[i + 1];
  }
  for (int i = 0; i < m; i++) {
    int s, ss;
    cin >> s >> ss;
    unite(s, ss);
  }
  int ans = 0;
  for (int i = 1; i <= n; i++) {
    if (root(i) == root(p[i])) {
      ans++;
    }
  }
  cout << ans << endl;
}
Problem p03354 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>

using namespace std;

#define rep(i, n) REP(i, 0, (n))
#define REP(i, a, n) for (int i = (a); i < (n); i++)

struct UnionFind {
  vector<int> data;
  UnionFind(int size) : data(size, -1) {}
  bool unionSet(int x, int y) {
    x = root(x);
    y = root(y);
    if (x != y) {
      if (data[y] < data[x])
        swap(x, y);
      data[x] += data[y];
      data[y] = x;
    }
    return x != y;
  }
  bool findSet(int x, int y) { return root(x) == root(y); }
  int root(int x) { return data[x] < 0 ? x : data[x] = root(data[x]); }
  int size(int x) { return -data[root(x)]; }
};

int N, M;
int p[100010];

int main() {
  cin >> N >> M;
  rep(i, N) cin >> p[i + 1];

  UnionFind uf(N);
  rep(j, M) {
    int x, y;
    cin >> x >> y;
    uf.unionSet(x, y);
  }

  int ans = 0;
  rep(i, N) if (uf.findSet(i + 1, p[i + 1])) ans++;
  cout << ans << endl;
}


Fixed submission:
#include <bits/stdc++.h>

using namespace std;

#define rep(i, n) REP(i, 0, (n))
#define REP(i, a, n) for (int i = (a); i < (n); i++)

struct UnionFind {
  vector<int> data;
  UnionFind(int size) : data(size, -1) {}
  bool unionSet(int x, int y) {
    x = root(x);
    y = root(y);
    if (x != y) {
      if (data[y] < data[x])
        swap(x, y);
      data[x] += data[y];
      data[y] = x;
    }
    return x != y;
  }
  bool findSet(int x, int y) { return root(x) == root(y); }
  int root(int x) { return data[x] < 0 ? x : data[x] = root(data[x]); }
  int size(int x) { return -data[root(x)]; }
};

int N, M;
int p[100010];

int main() {
  cin >> N >> M;
  rep(i, N) cin >> p[i + 1];

  UnionFind uf(N + 1);
  rep(j, M) {
    int x, y;
    cin >> x >> y;
    uf.unionSet(x, y);
  }

  int ans = 0;
  rep(i, N) if (uf.findSet(i + 1, p[i + 1])) ans++;
  cout << ans << endl;
}
Problem p03354 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (int)n; i++)
#define rep1(i, n) for (int i = 1; i <= (int)n; i++)
#define rep2(i, j, n) for (int j = i; j < n; j++)
#define rep3(i, j, n) for (int j = i; j <= n; j++)
#define rrep(i, n) for (int i = n - 1; i >= 0; i--)
#define sp(n) cout << fixed << setprecision(n)
typedef long long ll;
using namespace std;
using namespace std;
const int MAX_N = 10002;
int par[MAX_N];  // 親
int pank[MAX_N]; // 木の深さ

// n要素で初期化
void init(int n) {
  for (int i = 0; i < n; i++) {
    par[i] = i;
    pank[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 (pank[x] < pank[y]) {
    par[x] = y;
  } else {
    par[y] = x;
    if (pank[x] == pank[y])
      pank[x]++;
  }
}

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

int main(void) {
  int n, m;
  cin >> n >> m;
  init(n);
  map<int, int> mp;
  rep(i, n) {
    int x;
    cin >> x;
    x--;
    mp[i] = x;
  }
  rep(i, m) {
    int a, b;
    cin >> a >> b;
    a--;
    b--;
    unite(a, b);
  }
  vector<bool> sol(n, false);
  int res = 0;
  rep(i, n) {
    int x = i, y = mp[i];
    if (same(x, y)) {
      if (!sol[x]) {
        sol[x] = true;
        res++;
        // cout<<1<<endl;
      }
    }
  }
  cout << res << endl;
}

Fixed submission:
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (int)n; i++)
#define rep1(i, n) for (int i = 1; i <= (int)n; i++)
#define rep2(i, j, n) for (int j = i; j < n; j++)
#define rep3(i, j, n) for (int j = i; j <= n; j++)
#define rrep(i, n) for (int i = n - 1; i >= 0; i--)
#define sp(n) cout << fixed << setprecision(n)
typedef long long ll;
using namespace std;
using namespace std;
const int MAX_N = 100002;
int par[MAX_N];  // 親
int pank[MAX_N]; // 木の深さ

// n要素で初期化
void init(int n) {
  for (int i = 0; i < n; i++) {
    par[i] = i;
    pank[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 (pank[x] < pank[y]) {
    par[x] = y;
  } else {
    par[y] = x;
    if (pank[x] == pank[y])
      pank[x]++;
  }
}

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

int main(void) {
  int n, m;
  cin >> n >> m;
  init(n);
  map<int, int> mp;
  rep(i, n) {
    int x;
    cin >> x;
    x--;
    mp[i] = x;
  }
  rep(i, m) {
    int a, b;
    cin >> a >> b;
    a--;
    b--;
    unite(a, b);
  }
  vector<bool> sol(n, false);
  int res = 0;
  rep(i, n) {
    int x = i, y = mp[i];
    if (same(x, y)) {
      if (!sol[x]) {
        sol[x] = true;
        res++;
        // cout<<1<<endl;
      }
    }
  }
  cout << res << endl;
}
Problem p03354 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
using namespace std;

const int MAX = 100005;

vector<int> A(MAX);
vector<int> parent(MAX);

int root(int a) {
  if (parent[a] == a)
    return a;
  else
    return root(parent[a]);
}
void unite(int a, int b) {
  if (root(a) != root(b)) {
    parent[root(b)] = root(a);
  }
}
bool check(int a, int b) {
  if (root(a) == root(b))
    return 1;
  else
    return 0;
}

int main() {

  int N, M;
  cin >> N >> M;
  for (int i = 0; i < N; i++) {
    cin >> A[i];
    A[i]--;
    parent[i] = i;
  }
  for (int i = 0; i < M; i++) {
    int a, b;
    cin >> a >> b;
    a--;
    b--;
    unite(a, b);
  }
  int cnt = 0;
  for (int i = 0; i < N; i++) {
    if (check(i, A[i]))
      cnt++;
  }
  cout << cnt << endl;
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;

const int MAX = 100005;

vector<int> A(MAX);
vector<int> parent(MAX);

int root(int a) {
  if (parent[a] == a)
    return a;
  else
    return parent[a] = root(parent[a]);
}
void unite(int a, int b) {
  if (root(a) != root(b)) {
    parent[root(b)] = root(a);
  }
}
bool check(int a, int b) {
  if (root(a) == root(b))
    return 1;
  else
    return 0;
}

int main() {

  int N, M;
  cin >> N >> M;
  for (int i = 0; i < N; i++) {
    cin >> A[i];
    A[i]--;
    parent[i] = i;
  }
  for (int i = 0; i < M; i++) {
    int a, b;
    cin >> a >> b;
    a--;
    b--;
    unite(a, b);
  }
  int cnt = 0;
  for (int i = 0; i < N; i++) {
    if (check(i, A[i]))
      cnt++;
  }
  cout << cnt << endl;
}
Problem p03354 (C++)

Buggy submission (status: Runtime Error):

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

struct UnionFind {
  // par[i] : iの親
  vector<int> par;
  // 初期化（全てのノードが根）
  UnionFind(int N) : par(N) {
    for (int i = 0; i < N; i++)
      par[i] = i;
  }
  // xの根を見つける
  int root(int x) {
    if (par[x] == x)
      return x;
    return par[x] = root(par[x]);
  }
  // x,yが同じ集合に属するか
  bool same(int x, int y) { return root(x) == root(y); }
  // x,yが別の集合なら連結
  void unite(int x, int y) {
    if (root(x) == root(y))
      return;
    par[root(x)] = root(y);
  }
};

template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define INF 999999999

/*Solve*/

int main() {
  int n, m;
  cin >> n >> m;
  int p[100010];
  rep(i, n) cin >> p[i];
  int x[100010];
  int y[100010];
  rep(i, m) cin >> x[i] >> y[i];
  UnionFind tree(n); // 初期化

  rep(i, n) tree.unite(x[i] - 1, y[i] - 1); // グラフの連結
  int cnt = 0;
  rep(i, n) if (tree.same(p[i] - 1, i)) cnt++;

  cout << cnt << endl;
}

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

struct UnionFind {
  // par[i] : iの親
  vector<int> par;
  // 初期化（全てのノードが根）
  UnionFind(int N) : par(N) {
    for (int i = 0; i < N; i++)
      par[i] = i;
  }
  // xの根を見つける
  int root(int x) {
    if (par[x] == x)
      return x;
    return par[x] = root(par[x]);
  }
  // x,yが同じ集合に属するか
  bool same(int x, int y) { return root(x) == root(y); }
  // x,yが別の集合なら連結
  void unite(int x, int y) {
    if (root(x) == root(y))
      return;
    par[root(x)] = root(y);
  }
};

template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define INF 999999999

/*Solve*/

int main() {
  int n, m;
  cin >> n >> m;
  int p[100010];
  rep(i, n) cin >> p[i];
  int x[100010];
  int y[100010];
  rep(i, m) cin >> x[i] >> y[i];
  UnionFind tree(n); // 初期化

  rep(i, m) tree.unite(x[i] - 1, y[i] - 1); // グラフの連結
  int cnt = 0;
  rep(i, n) if (tree.same(p[i] - 1, i)) cnt++;

  cout << cnt << endl;
}
Problem p03354 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < n; i++)
#define INF 1000000007
using namespace std;

int main() {
  int n, m;
  cin >> n >> m;
  vector<int> p(n), x(m), y(m);
  rep(i, n) {
    cin >> p[i];
    p[i]--;
  }
  vector<int> uf(n);
  rep(i, n) uf[i] = INF;
  rep(i, m) {
    cin >> x[i] >> y[i];
    x[i]--;
    y[i]--;
    int rootx = x[i], rooty = y[i], stepx = 0, stepy = 0;
    while (uf[rootx] != rootx && uf[rootx] != INF) {
      stepx++;
      rootx = uf[rootx];
    }
    while (uf[rooty] != rooty && uf[rooty] != INF) {
      stepy++;
      rooty = uf[rooty];
    }
    if (rootx != rooty || (uf[rootx] == INF && uf[rooty] == INF)) {
      if (uf[rooty] == INF && uf[rootx] == INF) {
        uf[x[i]] = x[i];
        uf[y[i]] = x[i];
      } else if (uf[rooty] != INF && uf[rootx] == INF) {
        uf[x[i]] = rooty;
      } else if (uf[rootx] != INF && uf[rooty] == INF) {
        uf[y[i]] = rootx;
      } else {
        uf[rootx] = rooty;
      }
    }
  }
  int ans = 0;
  rep(i, n) {
    if (p[i] == i) {
      ans++;
      continue;
    }
    if (uf[i] == INF || uf[p[i]] == INF)
      continue;
    int pi = p[i];
    while (uf[pi] != pi)
      pi = uf[pi];
    int ii = i;
    while (uf[ii] != ii)
      ii = uf[ii];
    if (pi == ii)
      ans++;
  }
  cout << ans << endl;
  return 0;
}

Fixed submission:
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < n; i++)
#define INF 1000000007
using namespace std;

int main() {
  int n, m;
  cin >> n >> m;
  vector<int> p(n), x(m), y(m);
  rep(i, n) {
    cin >> p[i];
    p[i]--;
  }
  vector<int> uf(n);
  rep(i, n) uf[i] = INF;
  rep(i, m) {
    cin >> x[i] >> y[i];
    x[i]--;
    y[i]--;
    int rootx = x[i], rooty = y[i], stepx = 0, stepy = 0;
    while (uf[rootx] != rootx && uf[rootx] != INF) {
      stepx++;
      rootx = uf[rootx];
    }
    while (uf[rooty] != rooty && uf[rooty] != INF) {
      stepy++;
      rooty = uf[rooty];
    }
    if (rootx != rooty || (uf[rootx] == INF && uf[rooty] == INF)) {
      if (uf[rooty] == INF && uf[rootx] == INF) {
        uf[x[i]] = x[i];
        uf[y[i]] = x[i];
      } else if (uf[rooty] != INF && uf[rootx] == INF) {
        uf[x[i]] = rooty;
      } else if (uf[rootx] != INF && uf[rooty] == INF) {
        uf[y[i]] = rootx;
      } else {
        if (stepx > stepy)
          uf[rooty] = rootx;
        else
          uf[rootx] = rooty;
      }
    }
  }
  int ans = 0;
  rep(i, n) {
    if (p[i] == i) {
      ans++;
      continue;
    }
    if (uf[i] == INF || uf[p[i]] == INF)
      continue;
    int pi = p[i];
    while (uf[pi] != pi)
      pi = uf[pi];
    int ii = i;
    while (uf[ii] != ii)
      ii = uf[ii];
    if (pi == ii)
      ans++;
  }
  cout << ans << endl;
  return 0;
}
Problem p03354 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
int main() {
  int n, m;
  cin >> n >> m;
  int *p = new int[100000];
  for (int i = 0; i < n; i++)
    cin >> p[i];
  int *g = new int[100000];
  for (int i = 0; i < n; i++)
    g[i] = i;
  for (int i = 0; i < m; i++) {
    int x, y;
    cin >> x;
    cin >> y;
    x--;
    y--;
    while (g[x] != x) {
      x = g[x];
    }
    while (g[y] != y) {
      y = g[y];
    }
    if (g[x] != g[y])
      g[x] = g[y];
  }
  int count = 0;
  for (int i = 0; i < n; i++) {
    int v = p[i] - 1;
    int gi = i;
    int gv = v;
    while (gi != g[gi])
      gi = g[gi];
    while (gv != g[gv])
      gv = g[gv];
    if (gi == gv)
      count++;
  }
  cout << count << endl;

  return 0;
}


Fixed submission:
#include <algorithm>
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
int main() {
  int n, m;
  cin >> n >> m;
  int *p = new int[100000];
  for (int i = 0; i < n; i++)
    cin >> p[i];
  int *g = new int[100000];
  for (int i = 0; i < n; i++)
    g[i] = i;
  for (int i = 0; i < m; i++) {
    int x, y;
    cin >> x;
    cin >> y;
    x--;
    y--;
    while (g[x] != x) {
      x = g[x];
    }
    while (g[y] != y) {
      y = g[y];
    }
    if (g[y] > g[x])
      g[y] = g[x];
    else
      g[x] = g[y];
  }
  int count = 0;
  for (int i = 0; i < n; i++) {
    int v = p[i] - 1;
    int gi = i;
    int gv = v;
    while (gi != g[gi])
      gi = g[gi];
    while (gv != g[gv])
      gv = g[gv];
    if (gi == gv)
      count++;
  }
  cout << count << endl;

  return 0;
}
Problem p03354 (C++)

Buggy submission (status: Time Limit Exceeded):
#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; }

ll root(ll x, vll &parent) {
  if (parent[x] == x)
    return x;
  else
    return root(parent[x], parent);
}

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

  vll p(n);
  for (ll i = 0; i < n; i++)
    cin >> p[i];

  vector<vll> xy(m, vll(2));
  for (ll i = 0; i < m; i++) {
    cin >> xy[i][0] >> xy[i][1];
    if (xy[i][0] > xy[i][1])
      swap(xy[i][0], xy[i][1]);
  }

  vll parent(n);
  for (ll i = 0; i < n; i++)
    parent[i] = i;
  for (ll i = 0; i < m; i++) {
    parent[root(xy[i][1] - 1, parent)] = root(xy[i][0] - 1, parent);
  }

  ll cnt = 0;
  for (ll i = 0; i < n; i++) {
    if (root(i, parent) == root(p[i] - 1, parent))
      cnt++;
  }
  cout << cnt << 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; }

ll root(ll x, vll &parent) {
  if (parent[x] == x)
    return x;
  else
    return parent[x] = root(parent[x], parent);
}

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

  vll p(n);
  for (ll i = 0; i < n; i++)
    cin >> p[i];

  vector<vll> xy(m, vll(2));
  for (ll i = 0; i < m; i++) {
    cin >> xy[i][0] >> xy[i][1];
    if (xy[i][0] > xy[i][1])
      swap(xy[i][0], xy[i][1]);
  }

  vll parent(n);
  for (ll i = 0; i < n; i++)
    parent[i] = i;
  for (ll i = 0; i < m; i++) {
    parent[root(xy[i][1] - 1, parent)] = root(xy[i][0] - 1, parent);
  }

  ll cnt = 0;
  for (ll i = 0; i < n; i++) {
    if (root(i, parent) == root(p[i] - 1, parent))
      cnt++;
  }
  cout << cnt << endl;
}
Problem p03354 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <iostream>
#include <limits.h>
#include <vector>
using namespace std;

struct UnionFind {
  vector<int> par;
  vector<int> rank;
  UnionFind(int x) {
    par = vector<int>(x);
    rank = vector<int>(x, 1);
    for (int i = 0; i < x; i++) {
      par[i] = i;
    }
  }
  int root(int x) {
    if (par[x] == x) {
      return x;
    } else {
      return par[x] = root(par[x]);
    }
  }
  void unite(int x, int y) {
    x = root(x);
    y = root(y);
    if (x == y) {
      return;
    }
    if (rank[x] < rank[y]) {
      par[x] = y;
    } else {
      par[y] = x;
    }
    if (rank[x] == rank[y]) {
      rank[x]++;
    }
  }
  bool check(int x, int y) { return root(x) == root(y); }
};

int main() {
  int n, m;
  cin >> n >> m;
  vector<int> da(n);
  for (int i = 0; i > n; i++) {
    cin >> da[i];
  }
  UnionFind UN(n);
  for (int i = 0; i < m; i++) {
    int x, y;
    cin >> x >> y;
    UN.unite(x - 1, y - 1);
  }
  int ans = 0;
  for (int i = 0; i < n; i++) {
    if (UN.check(i, da[i] - 1)) {
      ans++;
    }
  }
  cout << ans << endl;
}

Fixed submission:
#include <algorithm>
#include <iostream>
#include <limits.h>
#include <vector>
using namespace std;

struct UnionFind {
  vector<int> par;
  vector<int> rank;
  UnionFind(int x) {
    par = vector<int>(x);
    rank = vector<int>(x, 1);
    for (int i = 0; i < x; i++) {
      par[i] = i;
    }
  }
  int root(int x) {
    if (par[x] == x) {
      return x;
    } else {
      return par[x] = root(par[x]);
    }
  }
  void unite(int x, int y) {
    x = root(x);
    y = root(y);
    if (x == y) {
      return;
    }
    if (rank[x] < rank[y]) {
      par[x] = y;
    } else {
      par[y] = x;
    }
    if (rank[x] == rank[y]) {
      rank[x]++;
    }
  }
  bool check(int x, int y) { return root(x) == root(y); }
};

int main() {
  int n, m;
  cin >> n >> m;
  vector<int> da(n);
  for (int i = 0; i < n; i++) {
    cin >> da[i];
  }
  UnionFind UN(n);
  for (int i = 0; i < m; i++) {
    int x, y;
    cin >> x >> y;
    UN.unite(x - 1, y - 1);
  }
  int ans = 0;
  for (int i = 0; i < n; i++) {
    if (UN.check(i, da[i] - 1)) {
      ans++;
    }
  }
  cout << ans << endl;
}
Problem p03354 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>

using namespace std;

const int inf = 0x3f3f3f3f;

struct node {
  int u, v;
};
node e[200050];
int head[100050], vis[100050], tr[100050], a[100050];
int cnt;
int n, m;

void addedge(int u, int v) {
  e[cnt].v = v;
  e[cnt].u = head[u];
  head[u] = cnt++;
}

int findx(int x) {
  if (tr[x] == x)
    return x;
  return tr[x] = findx(tr[x]);
}
void merge(int u, int v) {
  int fx = findx(u);
  int fy = findx(v);
  if (tr[fy] != fx)
    tr[fy] = fx;
}
void dfs(int u) {
  vis[u] = 1;
  for (int i = head[u]; i = -1; i = e[i].u) {
    int v = e[i].v;
    if (!vis[v]) {
      tr[v] = cnt;
      dfs(v);
    }
  }
}
void init() {
  cnt = 0;
  memset(head, -1, sizeof(head));
  memset(vis, 0, sizeof(vis));
  for (int i = 0; i < n; i++)
    tr[i] = i;
}
int main() {
  init();
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= n; ++i)
    scanf("%d", &a[i]);
  for (int i = 0; i < m; ++i) {
    int x, y;
    scanf("%d%d", &x, &y);
    addedge(x, y);
    addedge(y, x);
  }
  int ans = 0;
  cnt = 1;
  for (int i = 1; i <= n; ++i) {
    if (!vis[i]) {
      tr[i] = cnt;
      dfs(i);
      cnt++;
    }
    if (tr[a[i]] == tr[i])
      ans++;
  }
  printf("%d\n", ans);
  return 0;
}

Fixed submission:
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>

using namespace std;

const int inf = 0x3f3f3f3f;

struct node {
  int u, v;
};
node e[200050];
int head[100050], vis[100050], tr[100050], a[100050];
int cnt;
int n, m;

void addedge(int u, int v) {
  e[cnt].v = v;
  e[cnt].u = head[u];
  head[u] = cnt++;
}

int findx(int x) {
  if (tr[x] == x)
    return x;
  return tr[x] = findx(tr[x]);
}
void merge(int u, int v) {
  int fx = findx(u);
  int fy = findx(v);
  if (tr[fy] != fx)
    tr[fy] = fx;
}
void dfs(int u) {
  vis[u] = 1;
  for (int i = head[u]; i != -1; i = e[i].u) {
    int v = e[i].v;
    if (!vis[v]) {
      tr[v] = cnt;
      dfs(v);
    }
  }
}
void init() {
  cnt = 0;
  memset(head, -1, sizeof(head));
  memset(vis, 0, sizeof(vis));
  for (int i = 0; i < n; i++)
    tr[i] = i;
}
int main() {
  init();
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= n; ++i)
    scanf("%d", &a[i]);
  for (int i = 0; i < m; ++i) {
    int x, y;
    scanf("%d%d", &x, &y);
    addedge(x, y);
    addedge(y, x);
  }
  int ans = 0;
  cnt = 1;
  for (int i = 1; i <= n; ++i) {
    if (!vis[i]) {
      tr[i] = cnt;
      dfs(i);
      cnt++;
    }
    if (tr[a[i]] == tr[i])
      ans++;
  }
  printf("%d\n", ans);
  return 0;
}
Problem p03354 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <cmath>
#include <complex>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <unordered_map>
#include <vector>
using namespace std;

struct UnionFind {
  vector<int> parent;

  UnionFind(int n) : parent(n) {
    for (int i = 0; i < n; i++)
      parent[i] = i;
  }

  int root(int x) {
    if (parent[x] == x)
      return x;
    return root(parent[x]);
  }

  void unite(int x, int y) {
    int rootX = root(x);
    int rootY = root(y);
    if (rootX == rootY)
      return;
    parent[rootX] = rootY;
  }

  bool same(int x, int y) { return root(x) == root(y); }
};

int main() {
  int n, q;
  cin >> n >> q;

  UnionFind tree(n);
  int p[n];
  for (int i = 0; i < n; i++) {
    cin >> p[i];
    --p[i];
  }

  for (int i = 0; i < q; i++) {
    int a, b;
    cin >> a >> b;
    --a, --b;
    tree.unite(a, b);
  }

  int res = 0;
  for (int i = 0; i < n; i++) {
    if (tree.same(i, p[i]))
      ++res;
  }
  cout << res << endl;
}


Fixed submission:
#include <algorithm>
#include <cmath>
#include <complex>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <unordered_map>
#include <vector>
using namespace std;

struct UnionFind {
  vector<int> parent;

  UnionFind(int n) : parent(n) {
    for (int i = 0; i < n; i++)
      parent[i] = i;
  }

  int root(int x) {
    if (parent[x] == x)
      return x;
    return parent[x] = root(parent[x]);
  }

  void unite(int x, int y) {
    int rootX = root(x);
    int rootY = root(y);
    if (rootX == rootY)
      return;
    parent[rootX] = rootY;
  }

  bool same(int x, int y) { return root(x) == root(y); }
};

int main() {
  int n, q;
  cin >> n >> q;

  UnionFind tree(n);
  int p[n];
  for (int i = 0; i < n; i++) {
    cin >> p[i];
    --p[i];
  }

  for (int i = 0; i < q; i++) {
    int a, b;
    cin >> a >> b;
    --a, --b;
    tree.unite(a, b);
  }

  int res = 0;
  for (int i = 0; i < n; i++) {
    if (tree.same(i, p[i]))
      ++res;
  }
  cout << res << endl;
}