寻找牢固连接的组件

时间:2019-12-06 22:28:59

标签: algorithm kotlin graph-theory

亲爱的朋友,你好。

我正在尝试解决此问题:https://open.kattis.com/problems/loopycabdrivers

我想出了一个解决方案,基本上可以收集所有紧密连接的组件

import java.util.*
import kotlin.math.min

private fun readLn() = readLine()!! // string line
private fun readInt() = readLn().toInt() // single int
private fun readStrings() = readLn().split(" ") // list of strings
private fun readInts() = readStrings().map { it.toInt() } // list of ints





typealias Graph<T> = Map<T, List<T>>

fun getScc(graph: Graph<String>, allNodes: Set<String>): MutableList<List<String>> {
    val discoveryTime = mutableMapOf<String, Int>()
    val lowest = mutableMapOf<String, Int>()
    val stack = ArrayDeque<String>()
    var index = 0
    val strongComponents = mutableListOf<List<String>>()
    val resolved = mutableSetOf<String>()
    fun dfs(node: String) {
        index += 1
        discoveryTime[node] = index
        lowest[node] = index
        stack.addLast(node)
        for (neb in graph[node] ?: mutableListOf()) {
            if (neb in resolved) {
                continue
            }
            if (neb in discoveryTime) { //ancestor
                lowest[node] = min(discoveryTime[neb]!!, lowest[node]!!)
            } else {
                dfs(neb)
                lowest[node] = min(lowest[neb]!!, lowest[node]!!)
            }
        }
        if (lowest[node] == discoveryTime[node]) {
            val sc = mutableListOf<String>()

            val neb = stack.pollLast()!!
            resolved.add(neb)
            sc.add(neb)

            if (neb == node) {
                strongComponents.add(sc)
                return

            }
            while (stack.size > 0 && stack.peekLast()!! != node) {
                val neb = stack.pollLast()!!
                resolved.add(neb)
                sc.add(neb)
            }
            if (stack.size > 0 && stack.peekLast()!! == node) {
                val neb = stack.pollLast()
                resolved.add(neb)
                sc.add(neb)
            }
            strongComponents.add(sc)
        }
    }


    for (node in allNodes) {
        if (node !in resolved) {
            dfs(node)
        }
    }
    return strongComponents
}


fun main(args: Array<String>) {
    val g = mutableMapOf<String, MutableList<String>>()
    val n = readInt()
    val allNodes = mutableSetOf<String>()
    for (i in 0 until n) {
        val (u, v) = readLn().split(" ")
        g.computeIfAbsent(u) { mutableListOf<String>() }
        allNodes.add(u)
        allNodes.add(v)
        g[u]!!.add(v)
    }
    val strongComponents = getScc(g, allNodes).map { component -> component.sortedBy { it: String -> it } }
        .map { x -> x.joinToString(separator = " ") }.sorted()
    for (sc in strongComponents) {
        if (sc.split(" ").size == 1) {
            println("avoid $sc")

        } else {
            println("okay $sc")
        }
    }
}


这通过了示例,但是在隐藏的测试用例上失败了。

我希望在正确方向上提供一些指导,以指导我如何解决算法。

0 个答案:

没有答案