BOJ 11404 ν”Œλ‘œμ΄λ“œ

ν”Œλ‘œμ΄λ“œ

μ‹œκ°„ μ œν•œ λ©”λͺ¨λ¦¬ μ œν•œ
1초 256MB

문제

n(1 ≀ n ≀ 100)개의 λ„μ‹œκ°€ μžˆλ‹€. 그리고 ν•œ λ„μ‹œμ—μ„œ μΆœλ°œν•˜μ—¬ λ‹€λ₯Έ λ„μ‹œμ— λ„μ°©ν•˜λŠ” m(1 ≀ m ≀ 100,000)개의 λ²„μŠ€κ°€ μžˆλ‹€. 각 λ²„μŠ€λŠ” ν•œ 번 μ‚¬μš©ν•  λ•Œ ν•„μš”ν•œ λΉ„μš©μ΄ μžˆλ‹€. λͺ¨λ“  λ„μ‹œμ˜ 쌍 (A, B)에 λŒ€ν•΄μ„œ λ„μ‹œ Aμ—μ„œ B둜 κ°€λŠ”λ° ν•„μš”ν•œ λΉ„μš©μ˜ μ΅œμ†Ÿκ°’μ„ κ΅¬ν•˜λŠ” ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•˜μ‹œμ˜€.

μž…λ ₯

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

좜λ ₯

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

예제 μž…λ ₯

5
14
1 2 2
1 3 3
1 4 1
1 5 10
2 4 2
3 4 1
3 5 1
4 5 3
3 5 10
3 1 8
1 4 2
5 1 7
3 4 2
5 2 4

예제 좜λ ₯

0 2 3 1 4
12 0 15 2 5
8 5 0 1 1
10 7 13 0 3
7 4 10 6 0

풀이

μ•„λž˜μ˜ μ•Œκ³ λ¦¬μ¦˜ λΆ„λ₯˜μ™€ 같이 κ·Έλž˜ν”„μ™€ ν”Œλ‘œμ΄λ“œ μ›Œμ…œ μ•Œκ³ λ¦¬μ¦˜μ„ μ‚¬μš©ν•΄ ν•΄κ²°ν•  수 μžˆλ‹€.

2

ν”Œλ‘œμ΄λ“œ μ›Œμ…œ μ•Œκ³ λ¦¬μ¦˜

κ·Έλž˜ν”„μ˜ λͺ¨λ“  간선에 λŒ€ν•˜μ—¬ κ°€λŠ₯ν•œ λͺ¨λ“  경둜λ₯Ό λΉ„κ΅ν•˜λŠ” μ•Œκ³ λ¦¬μ¦˜ 이닀.
ν”Œλ‘œμ΄λ“œ μ›Œμ…œ μ•Œκ³ λ¦¬μ¦˜μ˜ μ‹œκ°„λ³΅μž‘λ„λŠ” V개의 간선에 λŒ€ν•˜μ—¬ O(V3)O(V^3)이닀.
두 개의 μ •μ κ°„μ˜ μ΅œλ‹¨ 경둜λ₯Ό 졜적이 될 λ•Œ κΉŒμ§€ κ°œμ„ ν•΄ μ΅œλ‹¨ 경둜λ₯Ό μ°ΎλŠ” μ•Œκ³ λ¦¬μ¦˜μ΄λ‹€.

μž…λ ₯ λ°›κΈ°

ν‘œμ€€ μž…μΆœλ ₯ ν•¨μˆ˜μΈ input을 μ‚¬μš©ν•˜μ§€ μ•Šκ³  sys을 importν•΄ μ‚¬μš©ν•˜μ˜€λ‹€.
μ €μž₯ν•  수 μžˆλŠ” κ°€μž₯ 큰 μ •μˆ˜λ₯Ό μ €μž₯ν•˜κΈ° μœ„ν•΄ INFλ³€μˆ˜λ₯Ό μ„ μ–Έν•˜κ³  sys.maxsizeλ₯Ό μ €μž₯ν–ˆλ‹€.
NΓ—NN \times N크기의 κ·Έλž˜ν”„λ₯Ό INF의 κ°’μœΌλ‘œ μ΄ˆκΈ°ν™” ν•œ ν›„ 정점과 κ°„μ„  정보 μž…λ ₯을 λ°›μ•˜λ‹€.
λ¬Έμ œμ—μ„œ μ‹œμž‘ λ„μ‹œμ™€ 도착 λ„μ‹œλ₯Ό μ—°κ²°ν•˜λŠ” 노선은 ν•˜λ‚˜κ°€ 아닐 수 μžˆλ‹€.λΌλŠ” 정보에 따라
minν•¨μˆ˜λ₯Ό μ΄μš©ν•΄ κΈ°μ‘΄ κ°’κ³Ό λΉ„κ΅ν•˜μ—¬ 더 적은 값을 ν•΄λ‹Ή κ°„μ„ μ˜ λΉ„μš©μœΌλ‘œ μ €μž₯ν•˜λ„λ‘ ν–ˆλ‹€.

import sys

input = sys.stdin.readline
INF = sys.maxsize

N = int(input())
M = int(input())
graph = [[INF for _ in range(N)] for _ in range(N)]

for _ in range(M):
    a, b, c = map(int, input().split())

    graph[a - 1][b - 1] = min(c, graph[a - 1][b - 1])

μ΅œμ†Œ λΉ„μš© 탐색

μ •μ μ˜ 갯수만큼 3쀑 λ°˜λ³΅λ¬Έμ„ μ§„ν–‰ν•œλ‹€.
일단 graph[i][i]즉 자기 μžμ‹ μ—μ„œ μžμ‹ μ˜ κ²½λ‘œλŠ” 0이기 λ•Œλ¬Έμ— 0으둜 μ €μž₯ν–ˆλ‹€.
이미 μ €μž₯λ˜μ–΄ μžˆλŠ” λΉ„μš©κ³Ό 정점 iλ₯Ό κ±°μ³μ„œ 정점 k둜 κ°€λŠ” μ΅œμ†Ÿκ°’μ„ μ°Ύμ•„ μ €μž₯ν•œλ‹€.

for i in range(N):
    graph[i][i] = 0

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

μ΅œμ†Œ λΉ„μš©μ΄ μ—…λ°μ΄νŠΈ λ˜λŠ” 것을 좜λ ₯해보면 μ•„λž˜μ™€ 같은 κ²°κ³Όκ°€ λ‚˜μ˜¨λ‹€.

  • 1번 정점을 ν†΅ν•˜μ—¬ 갈 수 μžˆλŠ” λͺ¨λ“  경우의 μ΅œμ†Ÿκ°’
===================== Now i is 0 =====================
         0          2          3          1         10
2147483647          0 2147483647          2 2147483647
         8         10          0          1          1
2147483647 2147483647 2147483647          0          3
         7          4         10          8          0
================== Updated Completed ==================
  • 2번 정점을 ν†΅ν•˜μ—¬ 갈 수 μžˆλŠ” λͺ¨λ“  경우의 μ΅œμ†Ÿκ°’
===================== Now i is 1 =====================
         0          2          3          1         10
2147483647          0 2147483647          2 2147483647
         8         10          0          1          1
2147483647 2147483647 2147483647          0          3
         7          4         10          6          0
================== Updated Completed ==================
  • 3번 정점을 ν†΅ν•˜μ—¬ 갈 수 μžˆλŠ” λͺ¨λ“  경우의 μ΅œμ†Ÿκ°’
===================== Now i is 2 =====================
         0          2          3          1          4
2147483647          0 2147483647          2 2147483647
         8         10          0          1          1
2147483647 2147483647 2147483647          0          3
         7          4         10          6          0
================== Updated Completed ==================
  • 4번 정점을 ν†΅ν•˜μ—¬ 갈 수 μžˆλŠ” λͺ¨λ“  경우의 μ΅œμ†Ÿκ°’
===================== Now i is 3 =====================
         0          2          3          1          4
2147483647          0 2147483647          2          5
         8         10          0          1          1
2147483647 2147483647 2147483647          0          3
         7          4         10          6          0
================== Updated Completed ==================
  • 5번 정점을 ν†΅ν•˜μ—¬ 갈 수 μžˆλŠ” λͺ¨λ“  경우의 μ΅œμ†Ÿκ°’
===================== Now i is 4 =====================
         0          2          3          1          4
        12          0         15          2          5
         8          5          0          1          1
        10          7         13          0          3
         7          4         10          6          0
================== Updated Completed ==================

λͺ¨λ“  μ •μ μ—μ„œ λ‹€λ₯Έ λͺ¨λ“  μ •μ μ—μ„œ λ°©λ¬Έν•  수 μžˆλŠ” λͺ¨λ“  μ΅œμ†Œ 경둜λ₯Ό μ°ΎλŠ” 것을 λ³Ό 수 μžˆλ‹€.

κ²°κ³Ό 좜λ ₯

경둜의 λΉ„μš©μ΄ 0μ΄κ±°λ‚˜ INF인 경우 0을 좜λ ₯ν•˜κ³ 
그렇지 μ•ŠμœΌλ©΄ graph[i][j]의 값을 κ·Έλƒ₯ 좜λ ₯ν•΄μ£Όλ©΄ λ˜λŠ” λ¬Έμ œλ‹€.

for i in range(N):
    for j in range(N):
        if graph[i][j] == 0 or graph[i][j] == INF:
            print(0, end=" ")

        else:
            print(graph[i][j], end=" ")
    print()

μ½”λ“œ κ΅¬ν˜„λΆ€

import sys

input = sys.stdin.readline
INF = sys.maxsize

N = int(input())
M = int(input())
graph = [[INF for _ in range(N)] for _ in range(N)]

for _ in range(M):
    a, b, c = map(int, input().split())

    graph[a - 1][b - 1] = min(c, graph[a - 1][b - 1])

for i in range(N):
    graph[i][i] = 0

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

for i in range(N):
    for j in range(N):
        if graph[i][j] == 0 or graph[i][j] == INF:
            print(0, end=" ")

        else:
            print(graph[i][j], end=" ")
    print()

κ²°κ³Ό

자료ꡬ쑰λ₯Ό λ°°μš΄μ§€ κ·Έλ ‡κ²Œ 였랜 μ‹œκ°„μ΄ μ§€λ‚˜μ§€ μ•Šμ•˜μŒμ—λ„ 기얡이 잘 λ‚˜μ§€ μ•Šμ•˜λ‹€.
λ‹€μ‹œ λ¦¬λ§ˆμΈλ“œν•˜λŠ” κ²Έν•΄μ„œ ν¬μŠ€νŒ…κ³Ό ν•¨κ»˜ 문제λ₯Ό ν’€μ–΄λ³΄μ•˜λ‹€.
기본적인 ν”Œλ‘œμ΄λ“œ μ›Œμ…œ μ•Œκ³ λ¦¬μ¦˜μ„ μ΄μš©ν•΄ ν•΄κ²°ν•  수 μžˆλŠ” λ¬Έμ œμ˜€λ‹€.

1

βœ… μ½”λ“œλŠ” [μ—¬κΈ°]μ—μ„œ 확인할 수 μžˆλ‹€.


Written by@Minsu Kim
Software Engineer at KakaoPay Corp.