Advertisement
vkazar

Untitled

Dec 1st, 2023
90
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Kotlin 4.22 KB | None | 0 0
  1. package sprint6.tasks.K
  2.  
  3. import java.io.BufferedReader
  4. import java.io.InputStreamReader
  5.  
  6. lateinit var vertexes: Map<Int, MutableMap<Int, Int>>
  7. lateinit var matrix: Map<Int, Array<Int>>
  8.  
  9. fun main() {
  10.     val buffer = BufferedReader(InputStreamReader(System.`in`))
  11.     val (vertexCount, edgeCount) = buffer.readLine().split(" ").map { it.toInt() }
  12.     //Список смежности
  13.     vertexes = List(vertexCount) { it + 1 }.associateWith { mutableMapOf() }
  14.     //Матрица результатов
  15.     matrix = List(vertexCount) { it + 1 }
  16.         .associateWith {
  17.             Array(vertexCount + 1) { Int.MAX_VALUE }
  18.         }
  19.  
  20.     //Заполнение списка смежности
  21.     repeat(edgeCount) {
  22.         //Считывание строки
  23.         val (vertex, toVertex, size) = buffer.readLine().split(" ").map { it.toInt() }
  24.         //Получение веса ребра между вершинами
  25.         val curSize = vertexes[vertex]!![toVertex]
  26.         //Если оно не указано или его вес больше считанного -- запомнить
  27.         if (curSize == null || curSize > size) {
  28.             //Т.к. граф неориентированный, каждое ребро ведёт в 2 стороны. Ну или есть 2 ребра в каждую сторону с одинаковым весом
  29.             vertexes[vertex]!![toVertex] = size
  30.             vertexes[toVertex]!![vertex] = size
  31.         }
  32.     }
  33.  
  34.     // Заполнение результата
  35.     matrix.forEach { (vertex, _) ->
  36.         //Расстояние рассчитывается построчно
  37.         //Т.е. для каждой строки применяется алгоритм Дейкстры
  38.         //Массив признаков посещённости
  39.         val visited = BooleanArray(vertexCount + 1) { false }
  40.         //Расстоянеи до текущей вершины равно нулю
  41.         matrix[vertex]!![vertex] = 0
  42.  
  43.         //Функция обновления расстояния
  44.         val relax: (Int, Int) -> Unit = { u, v ->
  45.             val potential = matrix[vertex]!![u] + vertexes[v]!![u]!!
  46.             val cur = matrix[vertex]!![v]
  47.             if (cur > potential) {
  48.                 matrix[vertex]!![v] = potential
  49.                 matrix[v]!![vertex] = potential
  50.             }
  51.         }
  52.  
  53.         while (true) {
  54.             // вершина на минимальном расстоянии от текущей. Если такой нет -- выход
  55.             val minDistVertex = getMinDistNotVisited(vertex, visited) ?: break
  56.             //Если ближайшая в бесконечности (нет пути), то выход
  57.             if (matrix[vertex]!![minDistVertex] == Int.MAX_VALUE) break
  58.  
  59.             visited[minDistVertex] = true
  60.             //Соседи текущей обрабатываемой вершины
  61.             val neighbours = vertexes[minDistVertex]!!.keys
  62.                 //Т.к. граф неориентированный, то матрица симметрична относительно главной диаогнали
  63.                 //А значит все вершины слева от нулевой длины уже обновлены в минимум в прошлых итерациях построчного перебора матрицы
  64.                 .filter { it > vertex }
  65.             for (n in neighbours) {
  66.                 relax(minDistVertex, n)
  67.             }
  68.         }
  69.     }
  70.    
  71.     //формирование ответа
  72.     buildString {
  73.         for (i in 1..vertexCount) {
  74.             for (j in 1..vertexCount)
  75.                 append("${matrix[i]!![j].takeIf { it != Int.MAX_VALUE } ?: -1} ")
  76.             appendLine()
  77.         }
  78.     }.let(::print)
  79. }
  80.  
  81. fun getMinDistNotVisited(forVertex: Int, visited: BooleanArray): Int? {
  82.     var currentMinimum = Int.MAX_VALUE
  83.     var currentMinimumVertex: Int? = null
  84.  
  85.     for (v in vertexes.keys) {
  86.         if (!visited[v] && matrix[forVertex]!![v] < currentMinimum) {
  87.             currentMinimum = matrix[forVertex]!![v]
  88.             currentMinimumVertex = v
  89.         }
  90.     }
  91.     return currentMinimumVertex
  92. }
  93.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement