본문 바로가기
알고리즘

Algorithm - 그래프 최단거리(플로이드-와샬)

by DGK 2022. 2. 6.

 

알고리즘 입문 수업을 듣고 중요한 내용을 정리했습니다.
개인 공부 후 자료를 남기기 위한 목적이므로 내용 상에 오류가 있을 수 있습니다.

 

문제

[그래프 최단거리(플로이드-와샬 : 냅색 알고리즘)]

 

N개의 도시가 주어지고, 각 도시들을 연결하는 도로와 해당 도로를 통행하는 비용이 주어질 때 모든 도시에서 모든 도시로 이동하는데 드는 비용의 최소값을 구하는 프로그램을 작성하시오.

 

 

 

*입력 설명

첫 번째 줄에는 도시의 수 N(1 ≤ N ≤ 100)과 도로 수 M(1 ≤ M ≤ 200)이 주어진다.

그 다음 줄부터 M줄에 걸쳐 도로정보와 비용(20 이하의 자연수)이 주어진다.

만약, 1번 도시와 2번 도시가 연결되고 그 비용이 13이면 "1, 2, 13"으로 정보가 주어진다.

 

*출력 설명

모든 도시에서 모든 도시로 이동하는데 드는 최소비용을 아래와 같이 출력한다.

단, 자기자신으로 가는 비용은 0이다.

또한, i노드에서 j노드로 갈 수 없을 때에는 비용을 "M"으로 출력한다.

 

 


 

 

풀이(Python)

답안

import sys
sys.stdin = open('AA/input_83.txt', 'rt')

if __name__ == "__main__":
    n, m = map(int, input().split())
    dis = [[5000]*(n+1) for _ in range(n+1)]
    for i in range(1, n+1):
        dis[i][i] = 0
    for i in range(m):
        a, b, c = map(int, input().split())
        dis[a][b] = c
    for k in range(1, n+1):
        for i in range(1, n+1):
            for j in range(1, n+1):
                dis[i][j] = min(dis[i][j], dis[i][k]+dis[k][j])
    for i in range(1, n+1):
        for j in range(1, n+1):
            if dis[i][j] == 5000:
                print("M", end=' ')
            else:
                print(dis[i][j], end=' ')
        print()
        
'''
출력 : 
0 5 3 6 13 
M 0 M 1 8 
M 2 0 3 10 
M 3 M 0 7 
M M M M 0 

'''

 

input_83.txt(입력)

5 8
1 2 6
1 3 3
3 2 2
2 4 1
2 5 13
3 4 5
4 2 3
4 5 7

 

 

중요내용

  1. 2차원 리스트 dis[i][j]는 i노드에서 j노드로 가는데 드는 최소비용을 의미한다.
  2. 2차원 리스트 dis의 초기 값으로 i노드에서 j노드로 오직 1번만 이동해서 가는데 드는 비용을 저장한다.
  3. 즉, 초기 값으로 어떠한 노드도 경유하지 않고 곧바로 i노드에서 j노드로 1번에 직행하는데 드는 최소비용을 저장하는 것이다.
  4. 참고로, 2차원 리스트 dis의 행번호는 i이고, 열번호는 j이다.
  5. 또한, 자신의 노드에서 자신의 노드로 가는데 드는 비용은 0이다. (ex, dis[i][i] = 0)
  6. 만약, k=3 이라면 dis[i][k] + dis[k][j] 값에는 k가 1일 때와 2일 때의 최소비용이 이미 적용된 것이다.
  7. 즉, dis[i][k] + dis[k][j] 값에는 i노드에서 j노드로 가는동안 1, 2, 3번 노드 중 일부 혹은 전부를 경유해서 가는 모든 경우의 수를 고려하여 최소비용을 구하고 해당 값을 저장하는 것이다.

 

 

댓글