class DisjoinSet { public: vector<int> rank, parent, size; int components; public: DisjoinSet(int n) { rank.resize(n + 1, 0); parent.resize(n + 1); size.resize(n + 1, 1); components = n; for (int i = 0; i <= n; i++) { parent[i] = i; } } int findUltParent(int node) { if (node == parent[node]) { return node; } return parent[node] = findUltParent(parent[node]); } void unionByRank(int u, int v) { int ulp_u = findUltParent(u); int ulp_v = findUltParent(v); if (ulp_u == ulp_v) return; if (rank[ulp_u] < rank[ulp_v]) { parent[ulp_v] = ulp_u; } else if (rank[ulp_u] > rank[ulp_v]) { parent[ulp_v] = ulp_u; } else { parent[ulp_v] = ulp_u; rank[ulp_u]++; } } void unionBySize(int u, int v) { int ulp_u = findUltParent(u); int ulp_v = findUltParent(v); if (ulp_u == ulp_v) return; if (size[ulp_u] < size[ulp_v]) { parent[ulp_u] = parent[ulp_v]; size[ulp_u] += size[ulp_v]; } else { parent[ulp_v] = parent[ulp_u]; size[ulp_v] += size[ulp_u]; } components--; } }; //findUltParent(u) or findUltParent(v) //unionBySize(u, v) //DisjoinSet ds = DisjoinSet(n)