오늘은 다익스트라 알고리즘에 대해서 알아보자.
다익스트라 알고리즘은 하나의 node에서 다른 node로 가는 최단경로를 구하고 싶을때 사용한다.
즉, 시작접에서 다른 모든 정점까지의 최단 경로의 길이를 찾는 알고리즘이다.
다익스트라 알고리즘을 사용할 수 있는 몇가지 조건이 있다.
위와 같은 조건들을 모두 충족해야만 다익스트라 알고리즘을 사용할 수 있다.
다익스트라 알고리즘은 일종의 길찾기 알고리즘이다.
길찾기 알고리즘에는 다양한 종류가 있으므로 위와 같은 조건을 만족 하지 않을때에는 크루스칼이나 벨만 포드와 같은 알고리즘을 사용할 수 있다.
나중에 알아보도록 하자.
다익스트라의 기본적인 아이디어를 살펴보자.
다익스트라를 구현하는데 필요한 변수는 아래와 같다.
시작점 A에서 최단거리를 구해보자.
distance
에 최단 거리를 저장하기로 했으니 아무 곳도 방문하지 않은 초기에는 최대값으로 배열을 초기화한다.
(Integer.MAX_VALUE
로 초기화하기도 하지만 최대 값이 10000이라면 10001로 초기화해도 된다.)
checked
에 노드 방문을 체크하기로 했으니 아무 곳도 방문하지 않은 초기에는 false로 배열을 초기화 한다.
A가 시작점이니 해당 노드 방문 거리는 0이다.
또한, 노드 방문을 체크하는 배열인 checked
도 true
로 변경한다.
현재 노드인 A와 연결되어 있는 노드들은 B와 C이다.
B 노드의 distance
가 2이므로 가장 작으므로 B 노드를 방문한다.
현재 노드인 B와 연결되어 있는 노드들 중 방문 가능한 노드들의 distance
를 갱신한다.
현재 B 노드에서는 C 노드를 방문할 수 있다.
❗️ 그런데 이미 C 노드의 distance
가 정해져 있다.
우리는 위에서 distance
배열에 최단 거리를 저장하기로 정했다.
A -> B -> C
의 총 거리는 3이다.
A -> C
의 총 거리는 4이다.
그러므로 우리는 C 노드의 distance
에는 3을 저장해야 한다.
백준 1753: 최단경로 문제로 이해해보자.
struct EdgeData: Comparable {
static func < (lhs: EdgeData, rhs: EdgeData) -> Bool {
lhs.cost < rhs.cost
}
var cost: Int
var node: Int
}
func solution() {
let inf = Int.max
let firstLine = readLine()!.split(separator: " ").map{ (subString) -> Int in
return Int(String(subString))!
}
let v = firstLine[0]
let e = firstLine[1]
let start = Int(readLine()!)! - 1
var graph = Array(repeating: [(Int, Int)](), count: v)
for _ in 0..<e {
let line = readLine()!.split(separator: " ").map( {Int(String($0))!} )
graph[line[0] - 1].append((line[1] - 1, line[2]))
}
var d = Array(repeating: inf, count: v)
d[start] = 0
var pq: Heap = Heap<EdgeData>()
pq.insert(EdgeData(cost: 0, node: start))
while(!pq.isEmpty) {
let now = pq.delete()!
if d[now.node] < now.cost {
continue
}
for next in graph[now.node] {
if now.cost + next.1 < d[next.0] {
d[next.0] = now.cost + next.1
pq.insert(EdgeData(cost: now.cost + next.1, node: next.0))
}
}
}
for i in d {
if i == inf {
print("INF")
} else {
print(i)
}
}
}
solution()
EdgeData
를 정의했다.오늘은 다익스트라 알고리즘에 대해서 알아봤다.
다익스트라를 알아야만 풀리는 문제들이 있어서 이참에 정리해봤다.
나중에 다른 길찾기 알고리즘들도 다뤄봐야지 그럼 이만👋
다익스트라 알고리즘 조건에서 "사이클이 없어야 한다."는 잘못된 설명인 것 같습니다
사이클을 가졌을 때 최단경로를 얻을 수 있는데 가중치가 양수일 때만 적용이 가능한 것으로 알고 있습니다.