https://coderun.yandex.ru/problem/dsu-ya-intern/description Средняя

Решение

import java.io.BufferedReader
import java.io.BufferedWriter
import java.io.InputStreamReader
import java.io.OutputStreamWriter

class DSU(n: Int) {
    private val parent = IntArray(n + 1) { it }
    private val rank = IntArray(n + 1)
    var components = n

    fun find(x: Int): Int {
        if (parent[x] != x) {
            parent[x] = find(parent[x]) // Path compression
        }
        return parent[x]
    }

    fun union(x: Int, y: Int) {
        val rootX = find(x)
        val rootY = find(y)
        if (rootX != rootY) {
            if (rank[rootX] < rank[rootY]) {
                parent[rootX] = rootY
            } else if (rank[rootX] > rank[rootY]) {
                parent[rootY] = rootX
            } else {
                parent[rootY] = rootX
                rank[rootX]++
            }
            components--
        }
    }
}

fun main() {
    val reader = BufferedReader(InputStreamReader(System.`in`))
    val writer = BufferedWriter(OutputStreamWriter(System.out))

    // Читаем N и M
    val (n, m) = reader.readLine().split(" ").map { it.toInt() }
    val edges = Array(m) { IntArray(2) }
    for (i in 0 until m) {
        val (x, y) = reader.readLine().split(" ").map { it.toInt() }
        edges[i] = intArrayOf(x, y)
    }

    // Читаем запросы
    val q = reader.readLine().toInt()
    val cuts = reader.readLine().split(" ").map { it.toInt() - 1 } // Переводим в 0-based
    val toCut = BooleanArray(m) { false }
    for (cut in cuts) {
        toCut[cut] = true
    }

    // Инициализируем DSU
    val dsu = DSU(n)

    // Добавляем рёбра, которые не будут разрезаны
    for (i in 0 until m) {
        if (!toCut[i]) {
            dsu.union(edges[i][0], edges[i][1])
        }
    }

    // Обрабатываем разрезы в обратном порядке
    val result = IntArray(q)
    for (i in q - 1 downTo 0) {
        result[i] = dsu.components
        val edge = edges[cuts[i]]
        dsu.union(edge[0], edge[1])
    }

    // Выводим результат
    writer.write(result.joinToString(" "))
    writer.newLine()

    reader.close()
    writer.close()
}