μ•Œκ³ λ¦¬μ¦˜/κ·Έλž˜ν”„

[λ°±μ€€ 11404 πŸ₯‡] ν”Œλ‘œμ΄λ“œ

1eehyunji 2023. 7. 13. 22:16

문제

n(2 ≤ n ≤ 100)개의 λ„μ‹œκ°€ μžˆλ‹€. 그리고 ν•œ λ„μ‹œμ—μ„œ μΆœλ°œν•˜μ—¬ λ‹€λ₯Έ λ„μ‹œμ— λ„μ°©ν•˜λŠ” m(1 ≤ m ≤ 100,000)개의 λ²„μŠ€κ°€ μžˆλ‹€. 각 λ²„μŠ€λŠ” ν•œ 번 μ‚¬μš©ν•  λ•Œ ν•„μš”ν•œ λΉ„μš©μ΄ μžˆλ‹€.

λͺ¨λ“  λ„μ‹œμ˜ 쌍 (A, B)에 λŒ€ν•΄μ„œ λ„μ‹œ Aμ—μ„œ B둜 κ°€λŠ”λ° ν•„μš”ν•œ λΉ„μš©μ˜ μ΅œμ†Ÿκ°’μ„ κ΅¬ν•˜λŠ” ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•˜μ‹œμ˜€.

μž…λ ₯

첫째 쀄에 λ„μ‹œμ˜ 개수 n이 μ£Όμ–΄μ§€κ³  λ‘˜μ§Έ μ€„μ—λŠ” λ²„μŠ€μ˜ 개수 m이 μ£Όμ–΄μ§„λ‹€. 그리고 μ…‹μ§Έ 쀄뢀터 m+2μ€„κΉŒμ§€ λ‹€μŒκ³Ό 같은 λ²„μŠ€μ˜ 정보가 μ£Όμ–΄μ§„λ‹€. λ¨Όμ € μ²˜μŒμ—λŠ” κ·Έ λ²„μŠ€μ˜ 좜발 λ„μ‹œμ˜ λ²ˆν˜Έκ°€ μ£Όμ–΄μ§„λ‹€. λ²„μŠ€μ˜ μ •λ³΄λŠ” λ²„μŠ€μ˜ μ‹œμž‘ λ„μ‹œ a, 도착 λ„μ‹œ b, ν•œ 번 νƒ€λŠ”λ° ν•„μš”ν•œ λΉ„μš© c둜 이루어져 μžˆλ‹€. μ‹œμž‘ λ„μ‹œμ™€ 도착 λ„μ‹œκ°€ 같은 κ²½μš°λŠ” μ—†λ‹€. λΉ„μš©μ€ 100,000보닀 μž‘κ±°λ‚˜ 같은 μžμ—°μˆ˜μ΄λ‹€.

μ‹œμž‘ λ„μ‹œμ™€ 도착 λ„μ‹œλ₯Ό μ—°κ²°ν•˜λŠ” 노선은 ν•˜λ‚˜κ°€ 아닐 수 μžˆλ‹€.

좜λ ₯

n개의 쀄을 좜λ ₯ν•΄μ•Ό ν•œλ‹€. i번째 쀄에 좜λ ₯ν•˜λŠ” j번째 μˆ«μžλŠ” λ„μ‹œ iμ—μ„œ j둜 κ°€λŠ”λ° ν•„μš”ν•œ μ΅œμ†Œ λΉ„μš©μ΄λ‹€. λ§Œμ•½, iμ—μ„œ j둜 갈 수 μ—†λŠ” κ²½μš°μ—λŠ” κ·Έ μžλ¦¬μ— 0을 좜λ ₯ν•œλ‹€.

 

λ¬Έμ œν’€μ΄

import sys

n=int(sys.stdin.readline())
m=int(sys.stdin.readline())

minimum=[[1e9]*(n+1) for _ in range(n+1)]

for _ in range(m):
    a,b,c=map(int, sys.stdin.readline().split(' '))
    # 이미 μ €μž₯된 κ²½λ‘œκ°€ μžˆλŠ” 경우, 더 μž‘μ€ 경둜λ₯Ό μ €μž₯
    if minimum[a][b]!=1e9:
        minimum[a][b]=min(c, minimum[a][b])
    else:
        minimum[a][b]=c

for i in range(1,n+1):
    minimum[i][i]=0

# 1~nκΉŒμ§€ 경유점 μ„€μ •ν•΄μ£Όλ©΄μ„œ μ΅œμ†Œκ°’ 탐색
for k in range(1,n+1):
    for i in range(1,n+1):
        for j in range(1, n+1):
            minimum[i][j]=min(minimum[i][j], minimum[i][k]+minimum[k][j])


for i in range(1,n+1):
    for j in range(1, n+1):
        # 도달할 수 μžˆλŠ” κ²½λ‘œκ°€ μ—†λŠ” 경우
        if minimum[i][j]==1e9:
            print(0, end=' ')
        else:
            print(minimum[i][j], end=' ')
    print('')

λͺ¨λ“  λ…Έλ“œκ°„μ˜ μ΅œλ‹¨ 경둜λ₯Ό κ΅¬ν•˜λŠ” 데에 μ“°μ΄λŠ” ν”Œλ‘œμ΄λ“œ μ›Œμ…œ(Floyd-Warshall) μ•Œκ³ λ¦¬μ¦˜μ„ μ‚¬μš©ν•΄μ•Ό ν•˜λŠ” λ¬Έμ œμ΄λ‹€. 

 

μ²˜μŒμ— μ΅œλ‹¨κ²½λ‘œλ₯Ό μ €μž₯ν•˜λŠ” 2차원 λ°°μ—΄ minimum을 INF κ°’μœΌλ‘œ μ΄ˆκΈ°ν™”ν•˜κ³ , κ°„μ„ μ˜ 개수 M만큼 μΆœλ°œμ§€(a), 도착지(b), μ†Œμš”μ‹œκ°„(c)λ₯Ό μž…λ ₯λ°›μ•„μ„œ minumum[a][b]=c ν˜•μ‹μœΌλ‘œ κ°„μ„  정보λ₯Ό μ €μž₯ν•œλ‹€. μ΄λ•Œ, λ™μΌν•œ κ²½λ‘œμ— λŒ€ν•΄μ„œ μ—¬λŸ¬ 개의 노선이 μ‘΄μž¬ν•  수 있고, μš°λ¦¬λŠ” μ΅œλ‹¨ 경둜λ₯Ό ꡬ해야 ν•˜κΈ° λ•Œλ¬Έμ— 이미 λ‹€λ₯Έ 노선이 μ‘΄μž¬ν•˜λŠ” 경우 더 μž‘μ€ 값을 μ €μž₯ν•œλ‹€. 

 

그리고 μΆœλ°œμ§€μ™€ 도착지가 같은 minimum[i][i]λŠ” 0으둜 μ΄ˆκΈ°ν™”ν•΄μ€€λ‹€. 

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

1λ²ˆλΆ€ν„° nλ²ˆκΉŒμ§€ λͺ¨λ‘ ν•œ λ²ˆμ”© 쀑간 λ…Έλ“œ 즉, κ²½μœ μ§€λ‘œ μ„ νƒν•˜λ©΄μ„œ 기쑴의 κ²½λ‘œλ³΄λ‹€ ν•΄λ‹Ή κ²½μœ μ§€λ₯Ό λ“€λ Έλ‹€ κ°€λŠ” 것이 더 짧은 경우 경둜λ₯Ό κ°±μ‹ ν•΄μ€€λ‹€. 

 

μ΄λ ‡κ²Œ ν•˜λ©΄ minimum[i][j]에 iμ—μ„œ j둜 κ°€λŠ” μ΅œλ‹¨ κ²½λ‘œκ°€ μ €μž₯λœλ‹€!

좜λ ₯ν•˜λŠ” κ³Όμ •μ—μ„œ minimum[i][j]κ°€ 1e9인 κ²½μš°μ—” ν•΄λ‹Ή κ²½λ‘œκ°€ μ—†λ‹€λŠ” λœ»μ΄λ―€λ‘œ 0을 좜λ ₯ν•΄μ€€λ‹€.

 

단, μ‹œκ°„λ³΅μž‘λ„ O(n^3)μ΄λ―€λ‘œ, ν•΄λ‹Ή μ‹œκ°„λ³΅μž‘λ„λ₯Ό λ§Œμ‘±ν•  수 μžˆλŠ” κ²½μš°μ—λ§Œ μ‚¬μš©ν•  수 μžˆλ‹€.