Algorithm/백준

[백준/Python] 플로이드

poppy 2021. 7. 4. 16:11
반응형

https://www.acmicpc.net/problem/11404

 

11404번: 플로이드

첫째 줄에 도시의 개수 n이 주어지고 둘째 줄에는 버스의 개수 m이 주어진다. 그리고 셋째 줄부터 m+2줄까지 다음과 같은 버스의 정보가 주어진다. 먼저 처음에는 그 버스의 출발 도시의 번호가

www.acmicpc.net

이 문제는 전형적인 최단 경로 문제이며 플로이드 워셜 알고리즘을 이용하면 수월하게 풀 수 있었다. 플로이드 워셜 알고리즘을 알아야 풀 수 있어서 이 알고리즘을 모른다면 아래의 링크를 참고하면 좋을 것 같다.

 

https://it-garden.tistory.com/247

 

플로이드-워셜(Floyd-Warshall) 알고리즘 이론과 파이썬 구현

플로이드-워셜(Floyd-Warshall) 알고리즘 플로이드-워셜(Floyd-Warshall) 알고리즘은 모든 정점 사이의 최단 경로를 찾는 탐색 알고리즘입니다. 최단 경로는 길이 순으로 구해집니다. 플로이드 워셜 알

it-garden.tistory.com

INF = int(1e9) # 무한을 의미하는 값

n = int(input()) # 도시의 개수
m = int(input()) # 버스의 개수

graph = [[INF] * (n+1) for _ in range(n+1)] # 최소 비용을 담는 리스트

# 자기 자신에서 자기 자신으로 가는 비용은 0으로 초기화
for a in range(1, n+1):
  for b in range(1, n+1):
    if a == b:
      graph[a][b] = 0

# 입력 받은 버스의 정보로 초기화
for _ in range(m):
  a, b, c = map(int, input().split())
  if c < graph[a][b]: # 가장 짧은 정보만 저장
    graph[a][b] = c

# 플로이드 워셜 알고리즘 수행
for k in range(1, n+1):
  for a in range(1, n+1):
    for b in range(1, n+1):
      graph[a][b] = min(graph[a][b], graph[a][k] + graph[k][b])

# 수행 결과 출력
for a in range(1, n+1):
  for b in range(1, n+1):
    if graph[a][b] == INF: # 도달할 수 없는 경우엔 0 출력
      print(0, end = " ")
    else:
      print(graph[a][b], end = " ")
  print()

모든 지점에서 모든 지점까지 최소 비용을 구해야하는 문제이므로 플로이드 워셜 알고리즘을 사용해야 한다. graph는 모든 지점에서 모든 지점까지 최소 비용을 담는 2차원 리스트이다. 리스트를 n 까지가 아닌 n+1 까지로 생성한 이유는 도시의 번호와 리스트의 인덱스를 맞추기 위해서이다. ( 도시의 번호가 1부터 시작하므로!) 

 

1. 반복문을 통해 자기 자신에서 자기 자신으로 가는 비용은 0으로 초기화한다.

2. 반복문을 통해 입력받은 버스의 정보로 비용을 초기화한다. 이 때 중요한 것은 문제에서 "시작 도시와 도착 도시를 연결하는 노선은 하나가 아닐 수 있다" 라고 했으므로 if c < graph[a][b] 조건이 꼭 필요하다. 가장 짧은 정보만 저장할 수 있도록 한다.

3. 플로이드 워셜 알고리즘을 수행한다. 

4. 수행 결과를 출력한다. 이 때 문제에서 도달할 수 없는 경우에는 0을 출력하라고 했으므로 조건문을 통해 출력을 다르게 해주어야 한다.

반응형

'Algorithm > 백준' 카테고리의 다른 글

[백준/Python] 별 찍기 - 10  (0) 2021.08.14
[백준/Python] 특정 거리의 도시 찾기  (0) 2021.07.24
[백준/Python] 럭키 스트레이트  (0) 2021.05.14
[백준/Python] 카드 정렬하기  (0) 2021.05.08
[백준/Python] 안테나  (0) 2021.05.07