[Algorithm] Shortest Path

Updated:

๐Ÿ“ฃ
๋ณธ ํฌ์ŠคํŠธ๋Š” โ€˜์ด๊ฒƒ์ด ์ทจ์—…์„ ์œ„ํ•œ ์ฝ”๋”ฉ ํ…Œ์ŠคํŠธ๋‹ค with ํŒŒ์ด์ฌโ€™์„ ๊ณต๋ถ€ํ•˜๊ณ  ์ž‘์„ฑํ•˜์˜€์Šต๋‹ˆ๋‹ค :)
click > (์ด์ฝ”ํ…Œ 2021) ์ด๊ฒƒ์ด ์ทจ์—…์„ ์œ„ํ•œ ์ฝ”๋”ฉ ํ…Œ์ŠคํŠธ๋‹ค with ํŒŒ์ด์ฌ

Shortest Path

์ด๋ก 

์ตœ๋‹จ ๊ฒฝ๋กœ(Shortest Path) ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ํŠน์ • ์ง€์ ๊นŒ์ง€ ๊ฐ€์žฅ ๋น ๋ฅด๊ฒŒ ๋„๋‹ฌํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ฐพ๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด๋‹ค. ์ตœ๋‹จ ๊ฒฝ๋กœ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์œ ํ˜•์—๋Š” ๋‹ค์–‘ํ•œ ์ข…๋ฅ˜๊ฐ€ ์žˆ๋Š”๋ฐ ์ƒํ™ฉ์— ๋งž๋Š” ํšจ์œจ์ ์ธ ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด ์ด๋ฏธ ์ •๋ฆฝ๋˜์–ด ์žˆ๋‹ค.

์ตœ๋‹จ ๊ฒฝ๋กœ ๋ฌธ์ œ๋Š” ๋ณดํ†ต ๊ทธ๋ž˜ํ”„๋ฅผ ์ด์šฉํ•ด ๊ฐ ์ง€์ ์€ ๋…ธ๋“œ๋กœ, ์ง€์ ๊ฐ„ ์—ฐ๊ฒฐ๋œ ๋„๋กœ๋Š” ๊ฐ„์„ ์œผ๋กœ ํ‘œํ˜„๋œ๋‹ค. โžก๏ธ ๊ทธ๋ž˜ํ”„์˜ ํ‘œํ˜„ ๋ฐฉ์‹

์ตœ๋‹จ ๊ฒฝ๋กœ ์•Œ๊ณ ๋ฆฌ์ฆ˜๋Š” ํฌ๊ฒŒ 3์ข…๋ฅ˜๊ฐ€ ์žˆ๋‹ค.

  • ๋‹ค์ต์ŠคํŠธ๋ผ ์•Œ๊ณ ๋ฆฌ์ฆ˜ : ํ•œ ์ง€์ ์—์„œ ๋‹ค๋ฅธ ํŠน์ • ์ง€์ ๊นŒ์ง€์˜ ์ตœ๋‹จ ๊ฒฝ๋กœ๋ฅผ ๊ตฌํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ
  • ํ”Œ๋กœ์ด๋“œ ์›Œ์…œ ์•Œ๊ณ ๋ฆฌ์ฆ˜ : ๋ชจ๋“  ์ง€์ ์—์„œ ๋‹ค๋ฅธ ๋ชจ๋“  ์ง€์ ๊นŒ์ง€์˜ ์ตœ๋‹จ ๊ฒฝ๋กœ๋ฅผ ๋ชจ๋‘ ๊ตฌํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ
  • ๋ฒจ๋งŒ ํฌ๋“œ ์•Œ๊ณ ๋ฆฌ์ฆ˜ : ๊ฐ„์„ ์˜ ๊ฐ€์ค‘์น˜๊ฐ€ ์Œ์ˆ˜์ผ ๋•Œ, ํ•œ ๋…ธ๋“œ์—์„œ ๋‹ค๋ฅธ ๋…ธ๋“œ๊นŒ์ง€์˜ ์ตœ๋‹จ ๊ฑฐ๋ฆฌ๋ฅผ ๊ตฌํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜

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

๋‹ค์ต์ŠคํŠธ๋ผ ์ตœ๋‹จ ๊ฒฝ๋กœ ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ๊ทธ๋ž˜ํ”„์—์„œ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ๋…ธ๋“œ๊ฐ€ ์žˆ์„ ๋•Œ, ํŠน์ •ํ•œ ๋…ธ๋“œ์—์„œ ์ถœ๋ฐœํ•˜์—ฌ ๋‹ค๋ฅธ ๋…ธ๋“œ๋กœ ๊ฐ€๋Š” ๊ฐ๊ฐ์˜ ์ตœ๋‹จ ๊ฒฝ๋กœ๋ฅผ ๊ตฌํ•ด์ฃผ๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด๋‹ค.

๋‹ค์ต์ŠคํŠธ๋ผ ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ๋งค๋ฒˆ ๊ฐ€์žฅ ๋น„์šฉ์ด ์ ์€ ๋…ธ๋“œ๋ฅผ ์„ ํƒํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๊ทธ๋ฆฌ๋”” ์•Œ๊ณ ๋ฆฌ์ฆ˜์œผ๋กœ ๋ถ„๋ฅ˜๋œ๋‹ค. ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ์›๋ฆฌ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

1๏ธโƒฃ ์ถœ๋ฐœ ๋…ธ๋“œ๋ฅผ ์„ค์ •ํ•œ๋‹ค.

2๏ธโƒฃ ์ตœ๋‹จ ๊ฑฐ๋ฆฌ ํ…Œ์ด๋ธ”์„ ์ดˆ๊ธฐํ™”ํ•œ๋‹ค.

3๏ธโƒฃ ๋ฐฉ๋ฌธํ•˜์ง€ ์•Š์€ ๋…ธ๋“œ ์ค‘์—์„œ ์ตœ๋‹จ ๊ฑฐ๋ฆฌ๊ฐ€ ๊ฐ€์žฅ ์งง์€ ๋…ธ๋“œ๋ฅผ ์„ ํƒํ•œ๋‹ค.

4๏ธโƒฃ ํ•ด๋‹น ๋…ธ๋“œ๋ฅผ ๊ฑฐ์ณ ๋‹ค๋ฅธ ๋…ธ๋“œ๋กœ ๊ฐ€๋Š” ๋น„์šฉ์„ ๊ณ„์‚ฐํ•˜์—ฌ ์ตœ๋‹จ๊ฑฐ๋ฆฌ ํ…Œ์ด๋ธ”์„ ๊ฐฑ์‹ ํ•œ๋‹ค

5๏ธโƒฃ 3-4๊ณผ์ •์„ ๋ฐ˜๋ณตํ•œ๋‹ค.

๊ตฌํ˜„ ์ฝ”๋“œ

def dijkstra(start, distance, graph):
    q = []
    heapq.heappush(q,(0,start))
    distance[start] = 0
    while q:
        dist, node = heapq.heappop(q)
        if distance[node] < dist: # ์ด๋ฏธ ์ฒ˜๋ฆฌํ•œ ์  ์žˆ๋Š” ๋…ธ๋“œ๋ผ๋ฉด ๋ฌด์‹œ
            continue
        for i in graph[node]: # ํ˜„์žฌ ๋…ธ๋“œ์™€ ์—ฐ๊ฒฐ๋œ ๋…ธ๋“œ๋“ค ํ™•์ธ
            cost = dist+i[1] # ๊ฑฐ๋ฆฌ ๊ณ„์‚ฐ
            if cost < distance[i[0]]: # ํ˜„์žฌ ์ตœ๋‹จ๊ฑฐ๋ฆฌ๋ณด๋‹ค ์ž‘๋‹ค๋ฉด ๊ฐฑ์‹ ํ•˜๊ณ  ํž™์— push
                distance[i[0]] = cost
                heapq.heappush(q,(cost, i[0]))

์‹œ๊ฐ„ ๋ณต์žก๋„

  • ์ตœ๋‹จ ๊ฑฐ๋ฆฌ ํ…Œ์ด๋ธ”์„ ๋ฆฌ์ŠคํŠธ๋กœ ๊ตฌํ˜„ํ–ˆ์„ ๋•Œ โ†’ $O(V^2)$
  • ์ตœ๋‹จ ๊ฑฐ๋ฆฌ ํ…Œ์ด๋ธ”์„ ์šฐ์„ ์ˆœ์œ„ ํ(heap)์œผ๋กœ ๊ตฌํ˜„ํ–ˆ์„ ๋•Œ โ†’ $O(E*logV)$

ํ”Œ๋กœ์ด๋“œ ์›Œ์…œ ์•Œ๊ณ ๋ฆฌ์ฆ˜

ํ”Œ๋กœ์ด๋“œ ์›Œ์…œ ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ๋ชจ๋“  ์ง€์ ์—์„œ ๋‹ค๋ฅธ ๋ชจ๋“  ์ง€์ ๊นŒ์ง€์˜ ์ตœ๋‹จ ๊ฒฝ๋กœ๋ฅผ ๋ชจ๋‘ ๊ตฌํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์œผ๋กœ ์ ํ™”์‹์— ๋งž๊ฒŒ ๋™์ž‘ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋‹ค์ด๋‚˜๋ฏน ํ”„๋กœ๊ทธ๋ž˜๋ฐ์œผ๋กœ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

๋‹ค์ต์ŠคํŠธ๋ผ ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ๋‹จ๊ณ„๋งˆ๋‹ค ๋ฐฉ๋ฌธํ•˜์ง€ ์•Š์€ ๋…ธ๋“œ ์ค‘์—์„œ ์ตœ๋‹จ ๊ฑฐ๋ฆฌ๋ฅผ ๊ฐ€์ง€๋Š” ๋…ธ๋“œ๋ฅผ ํ•˜๋‚˜์”ฉ ์„ ํƒํ•œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ํ•ด๋‹น ๋…ธ๋“œ๋ฅผ ๊ฑฐ์ณ ๊ฐ€๋Š” ๊ฒฝ๋กœ๋ฅผ ํ™•์ธํ•˜๋ฉฐ ์ตœ๋‹จ ๊ฑฐ๋ฆฌ ํ…Œ์ด๋ธ”(1์ฐจ์› ๋ฆฌ์ŠคํŠธ)๋ฅผ ๊ฐฑ์‹ ํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค.

ํ”Œ๋กœ์ด๋“œ ์›Œ์…œ ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ๋‹จ๊ณ„๋งˆ๋‹ค ํ˜„์žฌ ๋…ธ๋“œ๋ฅผ ๊ฑฐ์ณ ๊ฐ€๋Š” ๋ชจ๋“  ๊ฒฝ๋กœ๋ฅผ ๊ณ ๋ คํ•œ๋‹ค. ๋ชจ๋“  ๋…ธ๋“œ์— ๋Œ€ํ•˜์—ฌ ๋‹ค๋ฅธ ๋ชจ๋“  ๋…ธ๋“œ๋กœ ๊ฐ€๋Š” ์ตœ๋‹จ ๊ฑฐ๋ฆฌ ์ •๋ณด๋ฅผ ๋ชจ๋‘ ๋‹ด์•„์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— 2์ฐจ์›์˜ ์ตœ๋‹จ ๊ฑฐ๋ฆฌ ํ…Œ์ด๋ธ”๋กœ ์ •๋ณด๋ฅผ ์ฒ˜๋ฆฌํ•œ๋‹ค. ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ์›๋ฆฌ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

1๏ธโƒฃ ํ˜„์žฌ ํ™•์ธํ•˜๊ณ  ์žˆ๋Š” ๋…ธ๋“œ๋ฅผ ์ œ์™ธํ•˜๊ณ , N-1๊ฐœ์˜ ๋…ธ๋“œ ์ค‘์—์„œ ์„œ๋กœ ๋‹ค๋ฅธ ๋…ธ๋“œ (A, B) ์Œ์„ ์„ ํƒํ•œ๋‹ค.

2๏ธโƒฃ A โ†’ ํ˜„์žฌ ๋…ธ๋“œ โ†’ B๋กœ ๊ฐ€๋Š” ๋น„์šฉ์„ ํ™•์ธํ•˜๊ณ  ์ตœ๋‹จ ๊ฑฐ๋ฆฌ๋ฅผ ๊ฐฑ์‹ ํ•˜๋‹ค.

๊ฐ ๋‹จ๊ณ„์—์„œ ์ตœ๋‹จ ๊ฑฐ๋ฆฌ๋ฅผ ๊ฐฑ์‹ ํ•˜๋Š” ์ ํ™”์‹์€ $D_{ab} = min(D_{ab}, D_{ak}+D_{kb})$ ์ด๋‹ค.

๊ตฌํ˜„ ์ฝ”๋“œ

for k in range(1,n+1):
    for i in range(1,n+1):
        for j in range(1,n+1):
            graph[i][j] = min(graph[i][j], graph[i][k]+graph[k][j])

์‹œ๊ฐ„ ๋ณต์žก๋„

N๊ฐœ์˜ ๋…ธ๋“œ์— ๋Œ€ํ•ด์„œ $_{n-1}P_2$๊ฐœ์˜ ์Œ์„ ๋ฐ˜๋ณตํ•ด์„œ ํ™•์ธํ•˜๋ฉด ๋˜๋ฏ€๋กœ $O(N^3)$์ด๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ๋‹ค.

๋ฒจ๋งŒ ํฌ๋“œ ์•Œ๊ณ ๋ฆฌ์ฆ˜

๋ฒจ๋งŒ ํฌ๋“œ ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ๋‹ค์ต์ŠคํŠธ๋ผ ์•Œ๊ณ ๋ฆฌ์ฆ˜๊ณผ ๋˜‘๊ฐ™์ด ํ•œ ๋…ธ๋“œ์—์„œ ๋‹ค๋ฅธ ๋…ธ๋“œ๊นŒ์ง€ ์ตœ๋‹จ ๊ฑฐ๋ฆฌ๋ฅผ ๊ตฌํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด๋‹ค. ์ฐจ์ด์ ์€ ๋ฒจ๋งŒ ํฌ๋“œ ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ๊ฐ„์„ ์˜ ๊ฐ€์ค‘์น˜๊ฐ€ ์Œ์ˆ˜์ผ ๋•Œ๋„ ์ตœ๋‹จ ๊ฑฐ๋ฆฌ๋ฅผ ๊ตฌํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์ด๋‹ค. ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ์›๋ฆฌ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

1๏ธโƒฃ ์ถœ๋ฐœ ๋…ธ๋“œ๋ฅผ ์„ค์ •ํ•œ๋‹ค.

2๏ธโƒฃ ์ตœ๋‹จ ๊ฑฐ๋ฆฌ ํ…Œ์ด๋ธ”์„ ์ดˆ๊ธฐํ™”ํ•œ๋‹ค.

3๏ธโƒฃ ๋ชจ๋“  ๊ฐ„์„  E๊ฐœ๋ฅผ ํ•˜๋‚˜์”ฉ ํ™•์ธํ•œ๋‹ค.

4๏ธโƒฃ ํ•ด๋‹น ๋…ธ๋“œ๋ฅผ ๊ฑฐ์ณ ๋‹ค๋ฅธ ๋…ธ๋“œ๋กœ ๊ฐ€๋Š” ๋น„์šฉ์„ ๊ณ„์‚ฐํ•˜์—ฌ ์ตœ๋‹จ๊ฑฐ๋ฆฌ ํ…Œ์ด๋ธ”์„ ๊ฐฑ์‹ ํ•œ๋‹ค

5๏ธโƒฃ 3-4๊ณผ์ •์„ ๋ฐ˜๋ณตํ•œ๋‹ค.

โœ… ์Œ์ˆ˜ ๊ฐ„์„  ์ˆœํ™˜(cycle) ๋ฐœ์ƒ์„ ํ™•์ธ!
4๏ธโƒฃ๋ฒˆ ๊ณผ์ •์„ ํ•œ ๋ฒˆ ๋” ์ˆ˜ํ–‰ํ•˜๊ณ  ์ด๋•Œ ์ตœ๋‹จ ๊ฑฐ๋ฆฌ ํ…Œ์ด๋ธ”์ด ๊ฐฑ์‹ ๋˜๋Š”์ง€๋ฅผ ํ™•์ธํ•œ๋‹ค. ๊ฐฑ์‹ ๋˜๋Š” ๊ฒฝ์šฐ ์Œ์ˆ˜ ๊ฐ„์„  ์ˆœํ™˜์ด ์กด์žฌํ•œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.
์Œ์ˆ˜ ๊ฐ„์„  ์ˆœํ™˜์ด ์กด์žฌํ•˜๋Š” ๊ฒฝ์šฐ ๋น„์šฉ์„ ๋ฌดํ•œํžˆ ์ค„์ผ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ตœ๋‹จ ๊ฑฐ๋ฆฌ๋ฅผ ์ˆ˜ํ•  ์ˆ˜ ์—†๊ฒŒ ๋˜๋ฏ€๋กœ ๊ผญ ํ™•์ธํ•ด์•ผ ํ•œ๋‹ค.

๊ตฌํ˜„ ์ฝ”๋“œ

def bellmanFord(start):
    distance[start] = 0
    for i in range(v): # ์ „์ฒด v - 1๋ฒˆ ๋ฐ˜๋ณต
        for j in range(e): # ๋งค ๋ฐ˜๋ณต๋งˆ๋‹ค '๋ชจ๋“  ๊ฐ„์„ '์„ ํ™•์ธํ•œ๋‹ค.
            cur_node = edges[j][0]
            next_node = edges[j][1]
            edge_cost = edges[j][2]
            # ํ˜„์žฌ ๊ฐ„์„ ์„ ๊ฑฐ์ณ์„œ ๋‹ค๋ฅธ ๋…ธ๋“œ๋กœ ์ด๋™ํ•˜๋Š” ๊ฑฐ๋ฆฌ๊ฐ€ ๋” ์งง์€ ๊ฒฝ์šฐ
            if distance[cur_node] != INF and distance[next_node] > distance[cur_node] + edge_cost:
                distance[next_node] = distance[cur_node] + edge_cost
                # v๋ฒˆ์งธ ๋ผ์šด๋“œ์—์„œ๋„ ๊ฐ’์ด ๊ฐฑ์‹ ๋œ๋‹ค๋ฉด ์Œ์ˆ˜ ์ˆœํ™˜์ด ์กด์žฌ
                if i == v - 1:
                    return True
    return False

REF : https://deep-learning-study.tistory.com/587

์‹œ๊ฐ„ ๋ณต์žก๋„

๋ชจ๋“  ๋…ธ๋“œ์—์„œ ๋ชจ๋“  ๊ฐ„์„ ์„ ํ™•์ธํ•˜๋ฏ€๋กœ O(VE)์ด๋‹ค.

์‹ค์ „ ๋ฌธ์ œ

[์‹ค์ „๋ฌธ์ œ 1] ๋ฏธ๋ž˜๋„์‹œ

INF = int(1e9)

n, m = map(int, input().split())
graph = [[INF] * (n+1) for _ in range(n+1)]

for a in range(1,n+1):
		for b in range(1,n+1):
				if a == b: 
						graph[a][b] = 0 # ์ž๊ธฐ ์ž์‹  ๋น„์šฉ์€ 0์œผ๋กœ ์ดˆ๊ธฐํ™”

for _ in range(m):
		a, b = map(int, input().split())
		graph[a][b] = 1
		graph[b][a] = 1

x, k = map(int, input().split())

for k in range(1, n+1):
		for i in range(1, n+1):
				for j in range(1, n+1):
						graph[i][j] = min(graph[i][j], graph[i][k] + graph[k][j])

distance = graph[1][k] + graph[k][x]

if distance >= INF:
		print(-1)
else:
		print(distance)

[์‹ค์ „๋ฌธ์ œ 2] ์ „๋ณด

import heapq
import sys
input = sys.stdin.readline
INF = int(1e9) # ๋ฌดํ•œ์„ ์˜๋ฏธํ•˜๋Š” ๊ฐ’์œผ๋กœ 10์–ต์„ ์„ค์ •

# ๋…ธ๋“œ์˜ ๊ฐœ์ˆ˜, ๊ฐ„์„ ์˜ ๊ฐœ์ˆ˜, ์‹œ์ž‘ ๋…ธ๋“œ๋ฅผ ์ž…๋ ฅ๋ฐ›๊ธฐ
n, m, start = map(int, input().split())
# ๊ฐ ๋…ธ๋“œ์— ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๋Š” ๋…ธ๋“œ์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ๋‹ด๋Š” ๋ฆฌ์ŠคํŠธ๋ฅผ ๋งŒ๋“ค๊ธฐ
graph = [[] for i in range(n + 1)]
# ์ตœ๋‹จ ๊ฑฐ๋ฆฌ ํ…Œ์ด๋ธ”์„ ๋ชจ๋‘ ๋ฌดํ•œ์œผ๋กœ ์ดˆ๊ธฐํ™”
distance = [INF] * (n + 1)

# ๋ชจ๋“  ๊ฐ„์„  ์ •๋ณด๋ฅผ ์ž…๋ ฅ๋ฐ›๊ธฐ
for _ in range(m):
    x, y, z = map(int, input().split())
    # X๋ฒˆ ๋…ธ๋“œ์—์„œ Y๋ฒˆ ๋…ธ๋“œ๋กœ ๊ฐ€๋Š” ๋น„์šฉ์ด Z๋ผ๋Š” ์˜๋ฏธ
    graph[x].append((y, z))

def dijkstra(start):
   q = []
   # ์‹œ์ž‘ ๋…ธ๋“œ๋กœ ๊ฐ€๊ธฐ ์œ„ํ•œ ์ตœ๋‹จ ๊ฒฝ๋กœ๋Š” 0์œผ๋กœ ์„ค์ •ํ•˜์—ฌ, ํ์— ์‚ฝ์ž…
   heapq.heappush(q, (0, start))
   distance[start] = 0
   while q: # ํ๊ฐ€ ๋น„์–ด์žˆ์ง€ ์•Š๋‹ค๋ฉด
        # ๊ฐ€์žฅ ์ตœ๋‹จ ๊ฑฐ๋ฆฌ๊ฐ€ ์งง์€ ๋…ธ๋“œ์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ๊บผ๋‚ด๊ธฐ
        dist, now = heapq.heappop(q)
        if distance[now] < dist:
            continue
        # ํ˜„์žฌ ๋…ธ๋“œ์™€ ์—ฐ๊ฒฐ๋œ ๋‹ค๋ฅธ ์ธ์ ‘ํ•œ ๋…ธ๋“œ๋“ค์„ ํ™•์ธ
        for i in graph[now]:
            cost = dist + i[1]
            # ํ˜„์žฌ ๋…ธ๋“œ๋ฅผ ๊ฑฐ์ณ์„œ, ๋‹ค๋ฅธ ๋…ธ๋“œ๋กœ ์ด๋™ํ•˜๋Š” ๊ฑฐ๋ฆฌ๊ฐ€ ๋” ์งง์€ ๊ฒฝ์šฐ
            if cost < distance[i[0]]:
                distance[i[0]] = cost
                heapq.heappush(q, (cost, i[0]))

# ๋‹ค์ต์ŠคํŠธ๋ผ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์ˆ˜ํ–‰
dijkstra(start)

# ๋„๋‹ฌํ•  ์ˆ˜ ์žˆ๋Š” ๋…ธ๋“œ์˜ ๊ฐœ์ˆ˜
count = 0
# ๋„๋‹ฌํ•  ์ˆ˜ ์žˆ๋Š” ๋…ธ๋“œ ์ค‘์—์„œ, ๊ฐ€์žฅ ๋ฉ€๋ฆฌ ์žˆ๋Š” ๋…ธ๋“œ์™€์˜ ์ตœ๋‹จ ๊ฑฐ๋ฆฌ
max_distance = 0
for d in distance:
    # ๋„๋‹ฌํ•  ์ˆ˜ ์žˆ๋Š” ๋…ธ๋“œ์ธ ๊ฒฝ์šฐ
    if d != 1e9:
        count += 1
        max_distance = max(max_distance, d)

# ์‹œ์ž‘ ๋…ธ๋“œ๋Š” ์ œ์™ธํ•ด์•ผ ํ•˜๋ฏ€๋กœ count - 1์„ ์ถœ๋ ฅ
print(count - 1, max_distance)

๋Œ“๊ธ€๋‚จ๊ธฐ๊ธฐ