728x90
시간 제한 1초, 메모리 제한 256MB
# 조건
- 취미가 여행이고 특기가 여행인 정우는 이번에는 여러 섬들을 여행해보려고 한다.
- 정우가 목적지로 잡은 섬은 총 N개이며 N개의 섬들은 M개의 양방향 통행 다리가 이어져 있어서 한 섬에서 다른 섬으로 이동할 수 있는 여러 경로가 존재한다.
- 정우는 섬의 지도를 보다가 지도에 적힌 섬의 높이를 보고 문득 이런 생각을 하게 된다.
- “어떤 섬 A에서 출발하여 K개의 다리를 이동하였을 때, 도착할 수 있는 높이가 가장 낮은 섬의 높이는 무엇일까?”
- 정우가 궁금해하는 문제를 대신 해결해주자!
입력
- 입력의 첫째 줄에 N, M(2 ≤ N ≤ 100, 1 ≤ M ≤ 10,000)이 공백으로 구분되어 주어진다.
- 입력의 둘째 줄에 N개의 섬의 높이 H(0 ≤ H ≤ 10,000)가 공백으로 구분되어 주어진다.
- 입력의 셋째 줄 부터 M개의 줄에 섬의 연결을 나타내는 정수 X, Y가 공백으로 구분 되어 주어진다.(1 ≤ X, Y ≤ N)
- 이는 X, Y 두 섬이 양방향 통행 다리로 연결되어 있다는 의미다.
- 입력의 M+4째 줄에 정우가 궁금해하는 질의의 수 T(1 ≤ T ≤ 10,000)가 주어진다.
- 다음 T개의 줄에 현재의 위치 A(1 ≤ A ≤ N)와 이동해야 하는 다리의 수 K(1 ≤ K ≤ 500)가 주어진다.
출력
- 각 질의에 대해서 각 줄 마다 A번 섬에서 정확히 K번 이동하였을 때 도착 가능한 섬들의 높이 중 가장 낮은 섬의 높이를 출력한다.
- K번 이동하였을 때 도착 가능한 섬이 없을 경우 -1을 출력한다.
# 접근 방법
- 전형적인 DP 문제이다.
- DP[I][J]를 I번 섬에서 J번 건넜을 때 도착가능 한 가장 낮은 섬으로 사용해주며 탐색한다.
- DP[I][J] = min[dp[i][j], dfs(i와 연결 지, K-1)]
- 즉, a - b - c가 연결되어있다고 할 때, a에서 2번 이동하여 가장 낮은 섬이 c라면, b에서 1번 이동해서 가장 낮은 섬도 C이다.
- 우선 주어진 섬 간의 양방향 다리를 기록해준다.
- dp 배열을 큰 값으로 설정하여 생성해주고, 플로이드 - 워셜을 사용하여 최대 500의 이동을 하며 dp 값을 갱신해준다.
- 플로이드 - 워셜을 사용하면 각 정점에서 다른 정점까지의 최소 값이 기록되므로 마지막에 입력된 출발점에서 K번째의 값을 구해주면 된다.
- 마지막에 inf의 값이라면 -1을 출력해주는 처리를 해야한다.
- 다른 분들의 코드를 참고하면, dfs와 SPFA라는 벨만 - 포드를 업그레이드한 알고리즘을 사용해주는데
- 갱신되는 점에 연결되어 있는 간선을 이용하여 정점에 대한 비용을 갱신할 , 큐에 없다면 그 정점을 넣어주는 방식이다
import sys
sys.stdin = open('input.txt')
input =sys.stdin.readline
N, M = map(int, input().split())
get_value = lambda x: int(x) -1
dp = [[float('inf')] * 501 for _ in range(N)]
height = list(map(int, input().split()))
# 각 섬의 초기 높이 기
for i in range(N):
dp[i][0] = height[i]
island = [[] for _ in range(N)]
for _ in range(M):
a, b = map(get_value, input().split())
island[a].append(b)
island[b].append(a)
# dp에 미리 기록해두기
# 플로이드 워셜 활용
for i in range(1, 501):
for j in range(N):
temp = float('inf')
for v in island[j]:
temp = min(temp, dp[v][i-1])
dp[j][i] = temp
for _ in range(int(input())):
a, k = map(int, input().split())
a -= 1
val = dp[a][k]
if val == float('inf'):
print(-1)
else:
print(val)
728x90
'ALGORITHM > 다익스트라, 벨만포드, 플로이드워셜' 카테고리의 다른 글
[백준 2211번] 파이썬 - 네트워크 복구 (0) | 2023.08.26 |
---|---|
[백준 2224번] 파이썬 - 명제 증명 (0) | 2023.08.15 |
[프로그래머스 Lv3] 파이썬 - 등산 코스 정하기 (0) | 2023.07.29 |
[백준 22955번] 파이썬 - 고양이 도도의 탈출기 (0) | 2023.07.17 |
[백준 4485번] 파이썬 - 녹색 옷 입은 애가 젤다지? (0) | 2023.04.04 |