이 문제의 힌트는 다리의 중량 제한인 c가 10억(1,000,000,000) 이므로 cpu가 1초에 약 1억의 수를 연산할 수 있다고 가정하면 시간복잡도가 O(C)일 때 약 10초가 걸리게 되어 시간 초과가 발생한다.
이분 탐색을 활용하여 결정 문제('YES' or 'NO')를 최적화 알고리즘으로 바꾸어 해결하는 기법이다.
이 문제는 파라메트릭 서치를 이용하여
초기에 무게를 (최저 무게 + 최고 무게) // 2 로 설정한 후
이동할 수 있으면 'YES' 를 반환하고
정답에 저장한 후 무게를 늘려서 조건을 만족하는 더 큰 무게가 있는지 탐색한다.
이동할 수 없으면 'NO' 를 반환하고
무게를 작게 조정한 뒤 조건을 만족하는지 탐색한다.
import sys
from collections import deque
input = sys.stdin.readline
# n : 섬의 개수, m : 도로의 개수, graph = 섬들 간 의 연결 정보
n, m = map(int, input().split())
graph = [[] for _ in range(n + 1)]
for _ in range(m):
island_1, island_2, weight = map(int, input().split())
graph[island_1].append((island_2, weight))
graph[island_2].append((island_1, weight))
# 문제에서 주어진 이동 가능한 무게의 최대값, 최솟값
min_weight = 1
max_weight = 1000000000
# 시작 도시와 도착 도시
start_island, end_island = map(int, input().split())
# BFS
# 이동 가능하면 큐에 넣고, 방문
# 큐에서 꺼낸 도시가 도착도시이면, 방문이 가능하다는 의미이므로 return True
# 이동이 가능한 도시에 대해서 BFS 탐색을 다 했는데 탐색이 종료되지 않았다면
# 종료도시는 무게 제한 때문에 갈 수 없다는 의미이므로 return False
def bfs(mid_weight):
queue = deque([start_island])
visited = set()
visited.add(start_island)
while queue:
island = queue.popleft()
if island == end_island:
return True
for next, weight in graph[island]:
if next not in visited and mid_weight <= weight:
visited.add(next)
queue.append(next)
return False
# 이분 탐색으로 이동 가능한 무게 탐색
result = min_weight
while min_weight <= max_weight:
mid = (min_weight + max_weight) // 2
if bfs(mid):
result = mid
min_weight = mid + 1
else:
max_weight = mid - 1
print(result)