Uknow's Lab.
article thumbnail

https://www.acmicpc.net/problem/1854

 

1854번: K번째 최단경로 찾기

첫째 줄에 n, m, k가 주어진다. (1 ≤ n ≤ 1000, 0 ≤ m ≤ 2000000, 1 ≤ k ≤ 100) n과 m은 각각 김 조교가 여행을 고려하고 있는 도시들의 개수와, 도시 간에 존재하는 도로의 수이다. 이어지는 m개의 줄에

www.acmicpc.net

 

난이도 : 플래티넘 4
태그 : 자료 구조, 그래프 이론, 데이크스트라, 우선순위 큐

 

 

1. 설명

다익스트라가 최단 경로를 찾는 알고리즘이라면,

이번엔 이 다익스트라를 이용하여 K 번째 최단 경로를 찾는 문제입니다.

 

해당 문제 같은 경우는 우선순위 큐를 활용할 수 있습니다.

우선순위 큐를 내림차순 정렬로 지정하고,

각 우선순위 큐의 크기가 K개를 넘는다면 하나씩 빼면서 K개를 유지합니다.

 

 

 

2. 소스코드

<kotlin />
import java.util.* data class Node(val to: Int, val weight: Int) : Comparable<Node> { override fun compareTo(other: Node): Int { return this.weight - other.weight } } fun main() = with(System.`in`.bufferedReader()) { val (n, m, k) = readLine().split(" ").map { it.toInt() } val connection = Array(n + 1) { ArrayList<Node>() } repeat(m) { val st = StringTokenizer(readLine()) connection[st.nextToken().toInt()].add(Node(st.nextToken().toInt(), st.nextToken().toInt())) } val answerPQ = dijkstra(n, k, connection, 1) val sb = StringBuilder() for (i in 1..n) { if (answerPQ[i].size == k) { sb.append(answerPQ[i].poll()) } else { sb.append("-1") } sb.append("\n") } print(sb) } fun dijkstra(n: Int, k: Int, connection: Array<ArrayList<Node>>, startNode: Int): Array<PriorityQueue<Int>> { val pq = PriorityQueue<Node>() pq.offer(Node(startNode, 0)) val answerPQ = Array(n + 1) { PriorityQueue<Int>(Collections.reverseOrder()) } answerPQ[1].add(0) while (pq.isNotEmpty()) { val target = pq.poll() connection[target.to].forEach { nextNode -> val newWeight = nextNode.weight + target.weight if (answerPQ[nextNode.to].size < k) { answerPQ[nextNode.to].add(newWeight) pq.add(Node(nextNode.to, newWeight)) } else if (answerPQ[nextNode.to].peek() > newWeight) { answerPQ[nextNode.to].poll() answerPQ[nextNode.to].add(newWeight) pq.offer(Node(nextNode.to, newWeight)) } } } return answerPQ }

 

구현은 일반적인 다익스트라와 크게 다르지 않지만,

다음 노드를 탐색하는 과정에서 우선순위 큐에 있는 원소가 K개 미만이라면 그대로 가중치를 넣고,

만약 K개 이상이고, 가장 큰 값보다 현재의 가중치가 크다면

(우선순위 큐는 내림차순으로 지정되어 있으므로 마지막 원소가 현재 값 보다 크다면)

가장 큰 값을 빼내고 새 값을 추가합니다.

 

 

 

3. 후기

꽤나 머리를 싸맸던 문제였습니다.

다익스트라를 연습하다가, 조금씩 상위 문제를 풀 고 있는데,

역시 플래티넘은 상당히 버겁네요.

profile

Uknow's Lab.

@유노 Uknow

인생은 Byte와 Double 사이 Char다. 아무말이나 해봤습니다.