๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
โญ Personal_Study/Algorithm

[์•Œ๊ณ ๋ฆฌ์ฆ˜] ๋‹ค์ต์ŠคํŠธ๋ผ (Dijkstra)

by ํฌ์ŠคํŠธ์‰์ดํฌ 2022. 10. 1.

๋‹ค์ต์ŠคํŠธ๋ผ (Dijkstra)

๋‹ค์ต์ŠคํŠธ๋ผ ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด๋ž€

โœ” ์Œ์˜ ๊ฐ€์ค‘์น˜๊ฐ€ ์—†๋Š” ๊ทธ๋ž˜ํ”„์˜ ํ•œ ์ •์ ์—์„œ ๋ชจ๋“  ์ •์ ๊นŒ์ง€์˜ ์ตœ๋‹จ๊ฑฐ๋ฆฌ๋ฅผ ๊ฐ๊ฐ ๊ตฌํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜

๋‹ค์ต์ŠคํŠธ๋ผ ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ์›๋ฆฌ

ใ€€ใ€€ใ€€* P[a][b]: a์™€ b ์‚ฌ์ด์˜ ๊ฑฐ๋ฆฌ

  1. ์ถœ๋ฐœ์ ์œผ๋กœ๋ถ€ํ„ฐ ์ตœ๋‹จ๊ฑฐ๋ฆฌ๋ฅผ ์ €์žฅํ•  ๋ฐฐ์—ด distance[v]์„ ๋งŒ๋“ค๊ณ  ์ถœ๋ฐœ ๋…ธ๋“œ๋Š” 0, ๋‚˜๋จธ์ง€ ๋…ธ๋“œ๋“ค์€ ์ถฉ๋ถ„ํžˆ ํฐ ๊ฐ’์œผ๋กœ ์ดˆ๊ธฐํ™” ํ•œ๋‹ค.
  2. ํ˜„์žฌ ๋…ธ๋“œ Current๋ฅผ ์ถœ๋ฐœ ๋…ธ๋“œ์˜ ๋ฒˆํ˜ธ๋กœ ์„ค์ •ํ•œ๋‹ค.
  3. Current๋กœ๋ถ€ํ„ฐ ๊ฐˆ ์ˆ˜ ์žˆ๋Š” ์ž„์˜์˜ ๋…ธ๋“œ Next์— ๋Œ€ํ•ด distance[Current] + P[Current][Next](A๋ฅผ ๊ฑฐ์ณ์„œ B๋กœ ๊ฐ€๋Š” ์ตœ๋‹จ๊ฑฐ๋ฆฌ)์™€ distance[Next](ํ˜„์žฌ๊นŒ์ง€ ์•Œ๋ ค์ง„ B์˜ ์ตœ๋‹จ ๊ฑฐ๋ฆฌ)์˜ ๊ฐ’์„ ๋น„๊ตํ•ด์„œ ์งง์€ ๊ฐ’(์งง์€ ๊ฒฝ๋กœ)๋กœ ๊ฐฑ์‹ ํ•œ๋‹ค.
  4. Current์˜ ๋ชจ๋“  ์ด์›ƒ๋…ธ๋“œ Next์— ๋Œ€ํ•ด 3 ์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.
  5. Current์˜ ์ƒํƒœ๋ฅผ ‘visited=True’๋กœ ๋ฐ”๊ฟ”์ค€๋‹ค. (Current๋Š” ๋” ์ด์ƒ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค.)
  6. visited == False์ธ ๋…ธ๋“œ ์ค‘ ์ถœ๋ฐœ์ ์œผ๋กœ๋ถ€ํ„ฐ ๊ฑฐ๋ฆฌ๊ฐ€ ๊ฐ€์žฅ ์งง์€ ๋…ธ๋“œ๋ฅผ Current๋กœ ์„ค์ •ํ•œ๋‹ค.
  7. ๋„์ฐฉ ๋…ธ๋“œ๊ฐ€ 'visited == True’๊ฐ€ ๋˜๊ฑฐ๋‚˜, ๋” ์ด์ƒ ๋ฏธ๋ฐฉ๋ฌธ ๋…ธ๋“œ๋ฅผ ์„ ํƒํ•  ์ˆ˜ ์—†์„ ๋•Œ๊นŒ์ง€ 3 ~ 6์˜ ๊ณผ์ •์„ ๋ฐ˜๋ณตํ•œ๋‹ค.

๊ทธ๋ฆผ์œผ๋กœ ๋‚˜ํƒ€๋‚ธ ๋‹ค์ต์ŠคํŠธ๋ผ

image

์†Œ์Šค์ฝ”๋“œ (๊ธฐ๋ณธํ˜•ํƒœ: O(V^2))

# V: ์ •์ ์˜ ๊ฐœ์ˆ˜, E: ๊ฐ„์„ ์˜ ๊ฐœ์ˆ˜, start: ์ถœ๋ฐœ๋…ธ๋“œ
V, E = map(int, input().split())
start = int(input())
# visited: ๋ฐฉ๋ฌธ ์—ฌ๋ถ€ ํ‘œ์‹œ ๋ฐฐ์—ด
visited = [False for _ in range(V + 1)]
# distance: ์ตœ๋‹จ๊ฑฐ๋ฆฌ ํ…Œ์ด๋ธ” (์ถฉ๋ถ„ํžˆ ํฐ ๊ฐ’์œผ๋กœ ์ดˆ๊ธฐํ™”)
distance = [float('INF')for _ in range(V + 1)]

# graph: ์ธ์ ‘๋ฆฌ์ŠคํŠธ๋กœ ๊ตฌํ˜„ํ•œ ๊ทธ๋ž˜ํ”„
graph = [[] for _ in range(V + 1)]
for _ in range(E):
	node1, node2, weight = map(int, input().split())
	graph[node1].append((node2, weight))


# ๋ฏธ๋ฐฉ๋ฌธ ๋…ธ๋“œ ์ค‘์—์„œ ์ตœ๋‹จ๊ฑฐ๋ฆฌ์ธ ๋…ธ๋“œ๋ฅผ ์ฐพ๋Š” ํ•จ์ˆ˜
def next_node():
	min_val = float('INF')
	idx = 0
	
	# ๋ชจ๋“  ์ •์ ์— ๋Œ€ํ•ด ํƒ์ƒ‰
	for i in range(1, V + 1):
		# ๋ฏธ๋ฐฉ๋ฌธ ๋…ธ๋“œ ์ค‘ ์ตœ๋‹จ๊ฑฐ๋ฆฌ ๋…ธ๋“œ ํƒ์ƒ‰
		if distance[i] < min_val and not visited[i]:
			min_val = distance[i]
			idx = i
			
	# ๋…ธ๋“œ ๋ฒˆํ˜ธ ๋ฐ˜ํ™˜
	return idx


# ๋‹ค์ต์ŠคํŠธ๋ผ ํ•จ์ˆ˜
def dijkstra(start):

	# ์ถœ๋ฐœ์  ๊ฑฐ๋ฆฌ ๋ฐ ๋ฐฉ๋ฌธ ํ‘œ์‹œ
	distance[start] = 0
	visited[start] = True
	
	# ์ถœ๋ฐœ๋…ธ๋“œ์˜ ์ธ์ ‘๋…ธ๋“œ ์ตœ๋‹จ๊ฑฐ๋ฆฌ ํ…Œ์ด๋ธ” ๊ฐฑ์‹ 
	for adj in graph[start]:
		distance[adj[0]] = adj[1]
	
	# ๋‚˜๋จธ์ง€ ๋…ธ๋“œ ๋ชจ๋“  ๋…ธ๋“œ์— ๋Œ€ํ•ด ๋ฐ˜๋ณต
	for _ in range(V - 1):
	
		# ๋‹ค์Œ ๋…ธ๋“œ ์„ค์ • ๋ฐ ๋ฐฉ๋ฌธ ํ‘œ์‹œ
		current = next_node()
		visited[current] = True
		
		# ์ตœ๋‹จ ๊ฑฐ๋ฆฌ ๊ฐฑ์‹ 
		for adj in graph[current]:
			cost = distance[current] + adj[1]
			if cost < distance[adj[0]]:
				distance[adj[0]] = cost
				
	return


# ์ถœ๋ฐœ์ ์œผ๋กœ๋ถ€ํ„ฐ ๋‹ค์ต์ŠคํŠธ๋ผ
dijkstra(start)

# ์ตœ๋‹จ๊ฑฐ๋ฆฌ ํ…Œ์ด๋ธ” ์ถœ๋ ฅ
print(distance)

์šฐ์„ ์ˆœ์œ„ ํ๋ฅผ ์ด์šฉํ•œ ๋‹ค์ต์ŠคํŠธ๋ผ (O(ElogE))

โœ” ๊ธฐ๋ณธ ํ˜•ํƒœ์˜ ๋‹ค์ต์ŠคํŠธ๋ผ๋Š” ๋‹ค์Œ ๋…ธ๋“œ๋ฅผ ํƒ์ƒ‰ํ•˜๋Š” ๊ณผ์ •์—์„œ ๋ชจ๋“  ๋…ธ๋“œ๋ฅผ ์ˆœํšŒํ•˜๊ฒŒ ๋˜์–ด O(V^2)์˜ ์‹œ๊ฐ„ ๋ณต์žก๋„๋ฅผ ๊ฐ€์ง€๊ฒŒ ๋œ๋‹ค.
โœ” ์šฐ์„ ์ˆœ์œ„ํ(ํž™ํ)๋ฅผ ์ด์šฉํ•˜๋ฉด ์ตœ๋‹จ๊ฑฐ๋ฆฌ์™€ ์ •์  ์ •๋ณด๋ฅผ ์ €์žฅํ•ด๋’€๋‹ค๊ฐ€ ๋ฐ”๋กœ ๋‹ค์Œ ๋…ธ๋“œ๋ฅผ ๋ฝ‘์•„๋‚ผ ์ˆ˜ ์žˆ๋‹ค. -> O(ElogE)์˜ ์‹œ๊ฐ„๋ณต์žก๋„

์†Œ์Šค ์ฝ”๋“œ

import heapq

# ์šฐ์„ ์ˆœ์œ„ ํ๋ฅผ ์ด์šฉํ•œ ๋‹ค์ต์ŠคํŠธ๋ผ
def  dijkstra(start):
	# ์šฐ์„ ์ˆœ์œ„ํ ์„ ์–ธ
	queue = []
	# ์šฐ์„ ์ˆœ์œ„ ํ์— (0(์ถœ๋ฐœ์  ๊ฑฐ๋ฆฌ), ์ถœ๋ฐœ์ ) ์‚ฝ์ž…
	heapq.heappush(queue, (0, start))
	# ์ถœ๋ฐœ์  ๊ฑฐ๋ฆฌ ํ‘œ์‹œ
	distance[start] =  0
	
	# ์šฐ์„ ์ˆœ์œ„ ํ๊ฐ€ ๋นŒ ๋•Œ๊นŒ์ง€ ์ง„ํ–‰
	while queue:
		# ์ตœ๋‹จ๊ฑฐ๋ฆฌ ์ •์  ์ถ”์ถœ
		weight, node = heapq.heappop(queue)
		
		# ํ•ด๋‹น ์ •์ ์ด ์ตœ๋‹จ๊ฑฐ๋ฆฌ๊ฐ€ ๋งž์„ ๊ฒฝ์šฐ
		if distance[node] == weight:
			# ์ธ์ ‘ ์ •์ ์— ๋Œ€ํ•ด์„œ ์ตœ๋‹จ๊ฑฐ๋ฆฌ ๋น„๊ตํ•ด๊ฐ€๋ฉด์„œ ๊ฐฑ์‹  
			for  next  in graph[node]:
				cost = distance[node] +  next[1]			
				# ์ตœ๋‹จ ๊ฑฐ๋ฆฌ ๊ฐฑ์‹ ํ•  ๊ฒฝ์šฐ
				if cost < distance[next[0]]:
					distance[next[0]] = cost
					# ์šฐ์„ ์ˆœ์œ„ํ์— ๊ฑฐ๋ฆฌ์™€ ๋…ธ๋“œ ์ •๋ณด ์ €์žฅ
					heapq.heappush(queue, (cost, next[0]))
  
	return
   
# V: ์ •์ ์˜ ๊ฐœ์ˆ˜, E: ๊ฐ„์„ ์˜ ๊ฐœ์ˆ˜, start: ์ถœ๋ฐœ์ง€์ 
V, E =  map(int, input().split())
start = int(input())
# distance: ์ตœ๋‹จ๊ฑฐ๋ฆฌ ํ‘œ์‹œ ๋ฐฐ์—ด (์ถฉ๋ถ„ํžˆ ํฐ ๊ฐ’์œผ๋กœ ์ดˆ๊ธฐํ™”)
distance = [float('INF') for _ in  range(V +  1)]

# graph: ์ธ์ ‘๋ฆฌ์ŠคํŠธ๋กœ ๋‚˜ํƒ€๋‚ธ ๊ทธ๋ž˜ํ”„ 
graph = [[] for _ in  range(V +  1)]
for _ in  range(E):
	node1, node2, weight =  map(int, input().split())
	graph[node1].append((node2, weight))

# ์ถœ๋ฐœ์ง€์ ์œผ๋กœ๋ถ€ํ„ฐ ๋‹ค์ต์ŠคํŠธ๋ผ ํ•จ์ˆ˜ ์‹œํ–‰
dijkstra(start)

# ์ตœ๋‹จ๊ฑฐ๋ฆฌ ํ…Œ์ด๋ธ” ์ถœ๋ ฅ
print(distance)

'โญ Personal_Study > Algorithm' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

Segment Tree  (0) 2022.12.03
[์•Œ๊ณ ๋ฆฌ์ฆ˜] ์ตœ์†Œ ์‹ ์žฅ ํŠธ๋ฆฌ (MST)  (1) 2022.09.29
[์•Œ๊ณ ๋ฆฌ์ฆ˜] Union-Find  (1) 2022.09.28

๋Œ“๊ธ€