kotlin coding test course, Dijkstra

Problem Description

Given a graph, implement an algorithm to find the shortest path from one vertex to another.
The given graph is a directed graph, and each edge has a weight.
Vertices are represented by integers from 0 to N-1, and if there is an edge between two vertices, we know its weight.

Input Format:

  • The first line contains the number of vertices N (1 ≤ N ≤ 1000).
  • The second line contains the number of edges M (1 ≤ M ≤ 10000).
  • From the third line to the Mth line, the information of each edge is given.
    This is in the form of “A B C”, meaning there is an edge from A to B with weight C.
    (1 ≤ A, B ≤ N, 1 ≤ C ≤ 1000)
  • The last line contains the start point S (1 ≤ S ≤ N) and the end point E.

Solution Process

The Dijkstra algorithm is an algorithm for finding the shortest path from one vertex to another in a graph.
This algorithm works correctly only when there are no negative weights, so it is important to check whether the weights are non-negative.

Below is the implementation process of the Dijkstra algorithm using Kotlin.

1. Graph Representation

To represent the graph, we use an adjacency list.
For each vertex, we store the vertices reachable from that vertex and the weight of the edge.
For example, we can represent each vertex as a list using an integer array.


    val graph = Array(N) { mutableListOf>() }
    

2. Input Processing

Add the edge information received as input to the graph.
According to the input format, we store the information of each edge through a loop.


    for (i in 0 until M) {
        val (A, B, C) = readLine()!!.split(" ").map { it.toInt() }
        graph[A-1].add(Pair(B-1, C)) // Edge from A to B with weight C
    }
    

3. Dijkstra Algorithm Implementation

Implement the algorithm to find the current shortest path using a priority queue.
Below is the core logic of the Dijkstra algorithm.


    fun dijkstra(start: Int) {
        val distance = Array(N) { Int.MAX_VALUE }
        distance[start] = 0
        
        val pq = PriorityQueue>(compareBy { it.second })
        pq.add(Pair(start, 0))

        while (pq.isNotEmpty()) {
            val (current, dist) = pq.poll()

            if (dist > distance[current]) continue

            for (next in graph[current]) {
                val (nextNode, weight) = next
                val newDist = dist + weight

                if (newDist < distance[nextNode]) {
                    distance[nextNode] = newDist
                    pq.add(Pair(nextNode, newDist))
                }
            }
        }
    }
    

4. Output Result

Finally, calculate and print the shortest distance to the endpoint.
If the endpoint is unreachable, print -1.


    dijkstra(S - 1)
    val result = if (distance[E - 1] == Int.MAX_VALUE) -1 else distance[E - 1]
    println(result)
    

Entire Code

Based on the above logic, a complete code is as follows.


    import java.util.*

    fun main() {
        val (N, M) = readLine()!!.split(" ").map { it.toInt() }
        val graph = Array(N) { mutableListOf>() }

        for (i in 0 until M) {
            val (A, B, C) = readLine()!!.split(" ").map { it.toInt() }
            graph[A - 1].add(Pair(B - 1, C))
        }

        val (S, E) = readLine()!!.split(" ").map { it.toInt() }

        fun dijkstra(start: Int) {
            val distance = Array(N) { Int.MAX_VALUE }
            distance[start] = 0

            val pq = PriorityQueue>(compareBy { it.second })
            pq.add(Pair(start, 0))

            while (pq.isNotEmpty()) {
                val (current, dist) = pq.poll()

                if (dist > distance[current]) continue

                for (next in graph[current]) {
                    val (nextNode, weight) = next
                    val newDist = dist + weight

                    if (newDist < distance[nextNode]) {
                        distance[nextNode] = newDist
                        pq.add(Pair(nextNode, newDist))
                    }
                }
            }
            return distance
        }

        dijkstra(S - 1)
        val result = if (distance[E - 1] == Int.MAX_VALUE) -1 else distance[E - 1]
        println(result)
    }
    

Conclusion

The Dijkstra algorithm is a powerful tool that can be applied to various problems.
Through the process of implementing it in Kotlin, we could understand the structure of the graph and learn various techniques to enhance the algorithm's performance.

It is necessary to practice how to solve complex problems simply and implement them in code.
Also, try to develop the ability to solve various shortest path problems in the real world using the Dijkstra algorithm.