public UnionFind <T> Root() { if (isRoot) { return(this); } var root = Parent.Root(); Parent = root; return(root); }
static void Solve() { int n, m; ReadMulti(out n, out m); var a = new int[m]; var b = new int[m]; for (int i = 0; i < m; i++) { ReadMulti(out a[i], out b[i]); a[i]--; b[i]--; } var ans = new long[m]; ans[m - 1] = (long)n * (n - 1) / 2; UnionFind uni = new UnionFind(n); for (int i = m - 1; i >= 1; i--) { ans[i - 1] = ans[i]; long g1 = uni.Data[uni.Root(a[i])]; long g2 = uni.Data[uni.Root(b[i])]; long dif = g1 * g2; if (uni.Connect(a[i], b[i])) { ans[i - 1] -= dif; } } foreach (var item in ans) { WriteAnswer(item); } }
public static bool Connect(UnionFind <T> a, UnionFind <T> b) { var aRoot = a.Root(); var bRoot = b.Root(); if (aRoot == bRoot) { return(false); } aRoot.isRoot = false; aRoot.Parent = bRoot; bRoot.size += aRoot.size; return(true); }