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

[λ°±μ€€ 11657 πŸ₯‡] νƒ€μž„λ¨Έμ‹ 

1eehyunji 2023. 7. 13. 22:30

문제

N개의 λ„μ‹œκ°€ μžˆλ‹€. 그리고 ν•œ λ„μ‹œμ—μ„œ μΆœλ°œν•˜μ—¬ λ‹€λ₯Έ λ„μ‹œμ— λ„μ°©ν•˜λŠ” λ²„μŠ€κ°€ M개 μžˆλ‹€. 각 λ²„μŠ€λŠ” A, B, C둜 λ‚˜νƒ€λ‚Ό 수 μžˆλŠ”λ°, AλŠ” μ‹œμž‘λ„μ‹œ, BλŠ” λ„μ°©λ„μ‹œ, CλŠ” λ²„μŠ€λ₯Ό 타고 μ΄λ™ν•˜λŠ”λ° κ±Έλ¦¬λŠ” μ‹œκ°„μ΄λ‹€. μ‹œκ°„ Cκ°€ μ–‘μˆ˜κ°€ μ•„λ‹Œ κ²½μš°κ°€ μžˆλ‹€. C = 0인 κ²½μš°λŠ” μˆœκ°„ 이동을 ν•˜λŠ” 경우, C < 0인 κ²½μš°λŠ” νƒ€μž„λ¨Έμ‹ μœΌλ‘œ μ‹œκ°„μ„ λ˜λŒμ•„κ°€λŠ” κ²½μš°μ΄λ‹€.

1번 λ„μ‹œμ—μ„œ μΆœλ°œν•΄μ„œ λ‚˜λ¨Έμ§€ λ„μ‹œλ‘œ κ°€λŠ” κ°€μž₯ λΉ λ₯Έ μ‹œκ°„μ„ κ΅¬ν•˜λŠ” ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•˜μ‹œμ˜€.

μž…λ ₯

첫째 쀄에 λ„μ‹œμ˜ 개수 N (1 ≤ N ≤ 500), λ²„μŠ€ λ…Έμ„ μ˜ 개수 M (1 ≤ M ≤ 6,000)이 μ£Όμ–΄μ§„λ‹€. λ‘˜μ§Έ 쀄뢀터 M개의 μ€„μ—λŠ” λ²„μŠ€ λ…Έμ„ μ˜ 정보 A, B, C (1 ≤ A, B ≤ N, -10,000 ≤ C ≤ 10,000)κ°€ μ£Όμ–΄μ§„λ‹€. 

좜λ ₯

λ§Œμ•½ 1번 λ„μ‹œμ—μ„œ μΆœλ°œν•΄ μ–΄λ–€ λ„μ‹œλ‘œ κ°€λŠ” κ³Όμ •μ—μ„œ μ‹œκ°„μ„ λ¬΄ν•œνžˆ 였래 μ „μœΌλ‘œ 되돌릴 수 μžˆλ‹€λ©΄ 첫째 쀄에 -1을 좜λ ₯ν•œλ‹€. κ·Έλ ‡μ§€ μ•Šλ‹€λ©΄ N-1개 쀄에 걸쳐 각 쀄에 1번 λ„μ‹œμ—μ„œ μΆœλ°œν•΄ 2번 λ„μ‹œ, 3번 λ„μ‹œ, ..., N번 λ„μ‹œλ‘œ κ°€λŠ” κ°€μž₯ λΉ λ₯Έ μ‹œκ°„μ„ μˆœμ„œλŒ€λ‘œ 좜λ ₯ν•œλ‹€. λ§Œμ•½ ν•΄λ‹Ή λ„μ‹œλ‘œ κ°€λŠ” κ²½λ‘œκ°€ μ—†λ‹€λ©΄ λŒ€μ‹  -1을 좜λ ₯ν•œλ‹€.

 

λ¬Έμ œν’€μ΄

import sys
from collections import deque

n,m=map(int, sys.stdin.readline().split(' '))

route=[]
for _ in range(m):
    a,b,c=map(int, sys.stdin.readline().split(' '))
    route.append((a,b,c))

dist=[1e9]*(n+1)
dist[1]=0

for v in range(n):
    for s,e,w in route:
        if dist[s]!=1e9 and dist[e]>dist[s]+w:
            if v==n-1:
                print(-1)
                sys.exit(0)
            dist[e]=dist[s]+w

for d in dist[2:n+1]:
    if d!=1e9:
        print(d)
    else:
        print(-1)

ν•œ μ •μ μ—μ„œ μΆœλ°œν•΄μ„œ λͺ¨λ“  λ‹€λ₯Έ 정점에 λŒ€ν•œ μ΅œλ‹¨ 경둜λ₯Ό 탐색할 수 μžˆλŠ” 벨만 ν¬λ“œ(Bellman-Ford) μ•Œκ³ λ¦¬μ¦˜μ„ μ‚¬μš©ν–ˆλ‹€. 

λ‹€μ΅μŠ€νŠΈλΌ μ•Œκ³ λ¦¬μ¦˜κ³Ό 달리 음의 κ°€μ€‘μΉ˜λ₯Ό ν¬ν•¨ν•΄μ„œ μ΅œλ‹¨ 경둜λ₯Ό 탐색할 수 μžˆλ‹€λŠ” μ μ—μ„œ λ‹€μ΅μŠ€νŠΈλΌ μ•Œκ³ λ¦¬μ¦˜μ΄ μ•„λ‹Œ 벨만 ν¬λ“œ μ•Œκ³ λ¦¬μ¦˜μ„ μ‚¬μš©ν•΄μ•Ό ν–ˆλ‹€. 

 

(κ°€μ€‘μΉ˜κ°€ μžˆλŠ” κ·Έλž˜ν”„μ˜ μ΅œλ‹¨ 경둜λ₯Ό νƒμƒ‰ν•˜λŠ” μ•Œκ³ λ¦¬μ¦˜μΈ λ‹€μ΅μŠ€νŠΈλΌ, ν”Œλ‘œμ΄λ“œ μ›Œμ…œ, 벨만 ν¬λ“œ μ•Œκ³ λ¦¬μ¦˜μ˜ 차이점과 μ‚¬μš©ν•΄μ•Ό ν•˜λŠ” κ²½μš°λŠ” μΆ”ν›„ λ”°λ‘œ ν¬μŠ€νŒ…ν•  μ˜ˆμ •μ΄λ‹€.)

 

벨만 ν¬λ“œ μ•Œκ³ λ¦¬μ¦˜μ€ 음의 사이클이 μ—†κ³ , 정점이 V개인 κ·Έλž˜ν”„μ—μ„œ μ΅œλ‹¨ κ²½λ‘œλŠ” λ§Žμ•„λ΄μ•Ό V-1개의 간선을 μ§€λ‚œλ‹€λŠ” μƒκ°μ—μ„œ μΆœλ°œν•œλ‹€. 

λ”°λΌμ„œ, λͺ¨λ“  정점에 λŒ€ν•΄μ„œ V-1번의 λ°˜λ³΅μ„ 톡해 κ°€λŠ₯ν•œ λͺ¨λ“  경둜λ₯Ό νƒμƒ‰ν•΄μ„œ μ •ν™•ν•œ 닡을 λ‚Έλ‹€. (μ—¬κΈ°μ„œ V-1번 λ°˜λ³΅μ„ ν•  λ•Œ 이미 ν•œ 번 κ³„μ‚°λœ 정점에 λŒ€ν•΄μ„œλ§Œ λ°˜λ³΅ν•œλ‹€. 처음 μ‹œμž‘ν•  λ•Œ μ‹œμž‘ λ…Έλ“œμΈ 1번 λ…Έλ“œμ˜ μ΅œλ‹¨ 경둜λ₯Ό 0으둜 μ΄ˆκΈ°ν™”ν•΄μ£ΌλŠ” μ΄μœ μ΄κΈ°λ„ ν•˜λ‹€.)

 

μš°μ„  route 배열에 λͺ¨λ“  κ°„μ„ μ˜ 정보λ₯Ό (μΆœλ°œμ§€, 도착지, κ°€μ€‘μΉ˜) ν˜•νƒœλ‘œ μ €μž₯ν•œλ‹€. 

그리고 1λ²ˆμ—μ„œ λͺ¨λ“  λ…Έλ“œλ‘œ κ°€λŠ” μ΅œλ‹¨ 경둜λ₯Ό μ €μž₯ν•˜λŠ” dist 배열을 1e9둜 μ΄ˆκΈ°ν™”ν•˜κ³ , 좜발 λ…Έλ“œμΈ 1번 λ…Έλ“œμ˜ μ΅œλ‹¨ κ²½λ‘œλŠ” 0으둜 μ΄ˆκΈ°ν™”ν•œλ‹€.

for v in range(n):
    for s,e,w in route:
        if dist[s]!=1e9 and dist[e]>dist[s]+w:
            if v==n-1:
                print(-1)
                sys.exit(0)
            dist[e]=dist[s]+w

V-1번 λ°˜λ³΅ν•˜λ©΄μ„œ λͺ¨λ“  간선을 νƒμƒ‰ν•œλ‹€. dist[s] 즉, μ‹œμž‘ λ…Έλ“œ 1λ²ˆλΆ€ν„° ν˜„μž¬ 간선이 λ‚˜νƒ€λ‚΄λŠ” μ‹œμž‘μ κΉŒμ§€μ˜ μ΅œλ‹¨ κ²½λ‘œκ°€ ν•œ 번 κ³„μ‚°λœ κ²½μš°μΈμ§€ ν™•μΈν•˜κ³ (dist[s]!=1e9), dist[e] 즉, μ‹œμž‘ λ…Έλ“œ 1λ²ˆλΆ€ν„° ν˜„μž¬ 간선이 λ‚˜νƒ€λ‚΄λŠ” λ„μ°©μ κΉŒμ§€μ˜ μ΅œλ‹¨ κ²½λ‘œκ°€ s번 λ…Έλ“œλ₯Ό ν•œ 번 κ±°μ³μ„œ e번 λ…Έλ“œκΉŒμ§€ κ°€λŠ” κ²½λ‘œλ³΄λ‹€ 큰 κ²½μš°μ— dist[e] 값을 κ°±μ‹ ν•΄μ€€λ‹€. 

 

μ—¬κΈ°μ„œ, 음의 사이클을 μ°ΎκΈ° μœ„ν•΄μ„œ λ°˜λ³΅μ„ V-1번 μ•„λ‹ˆλΌ V번 λ°˜λ³΅ν•˜λŠ”λ°, μ—¬κΈ°μ„œ V번째 λ°˜λ³΅μ„ ν• λ•Œ 값이 κ°±μ‹ λ˜λŠ” κ²½μš°μ—” 음의 사이클이 μ‘΄μž¬ν•œλ‹€λŠ” λœ»μ΄λ―€λ‘œ -1을 좜λ ₯ν•˜κ³  ν”„λ‘œκ·Έλž¨μ„ μ’…λ£Œν•œλ‹€. 

 

μ΄λ ‡κ²Œ V-1번 λͺ¨λ“  간선을 νƒμƒ‰ν•΄μ„œ μ΅œλ‹¨ 경둜λ₯Ό κ°±μ‹ ν•΄μ£Όλ©΄ μ‹œμž‘ λ…Έλ“œλΆ€ν„° λͺ¨λ“  λ…Έλ“œκΉŒμ§€ κ°€λŠ” μ΅œλ‹¨ 경둜λ₯Ό dist 배열에 μ €μž₯ν•  수 μžˆλ‹€. 

좜λ ₯을 해쀄 λ•ŒλŠ” dist값이 1e9인 κ²½μš°μ—” ν•΄λ‹Ή λ…Έλ“œλ‘œ 갈 수 μžˆλŠ” κ²½λ‘œκ°€ μ—†λ‹€λŠ” 뜻이기 λ•Œλ¬Έμ— -1을 좜λ ₯ν•΄μ£Όκ³ , κ·Έλ ‡μ§€ μ•Šμ€ κ²½μš°μ—”  dist 값을 좜λ ₯ν•΄μ€€λ‹€.