관리 메뉴

커리까지

[백준] 1800번 인터넷 설치 파이썬 본문

알고리즘/풀이

[백준] 1800번 인터넷 설치 파이썬

목표는 커리 2022. 12. 22. 12:36
728x90
SMALL

문제

오늘 팀전을 다들 열심히 하시는 것을 보고 원장선생님은 세미나 실에 인터넷을 설치해 주기로 마음을 먹으셨다. 하지만 비 협조적인 코레스코 콘도는 원장님께서 학생들에게 인터넷 선을 연결하는 것에 대해서 일부에 대해 돈을 요구하였다.

각각의 학생들의 번호가 1부터 N까지 붙여져 있다고 하면 아무나 서로 인터넷 선이 연결되어 있지 않다. P(P<=10,000)개의 쌍만이 서로 이어 질수 있으며 서로 선을 연결하는데 가격이 다르다.

1번은 다행히 인터넷 서버와 바로 연결되어 있어 인터넷이 가능하다. 우리의 목표는 N번 컴퓨터가 인터넷에 연결하는 것이다. 나머지 컴퓨터는 연결 되어 있거나 연결 안되어 있어도 무방하다.

하지만 코레스코에서는 K개의 인터넷 선에 대해서는 공짜로 연결해주기로 하였다. 그리고 나머지 인터넷 선에 대해서는 남은 것 중 제일 가격이 비싼 것에 대해서만 가격을 받기로 하였다. 이때 원장선생님이 내게 되는 최소의 값을 구하여라.

입력

첫 번째 줄에 N(1 ≤ N ≤ 1,000), 케이블선의 개수 P(1 ≤ P ≤ 10,000), 공짜로 제공하는 케이블선의 개수 K(0 ≤ K < N)이 주어진다. 다음 P개의 줄에는 케이블이 연결하는 두 컴퓨터 번호와 그 가격이 차례로 들어온다. 가격은 1 이상 1,000,000 이하다.

출력

첫째 줄에 원장선생님이 내게 되는 최소의 돈을 출력한다. 만약 1번과 N번 컴퓨터를 잇는 것이 불가능 하다면 -1을 출력한다.

예제 입력 1
5 7 1
1 2 5
3 1 4
2 4 8
3 2 3
5 2 9
3 4 7
4 5 6
예제 출력 1
4

제출 답안

  • 도저히 방법이 생각이 안 난 문제다.
  • 구글링해서 답을 찾았다.
  • 핵심은 최소한의 비용을 정해놓고 그 비용 이상의 전선을 k번 만큼 가능한지 알아보는 것이다.
    • 그래서 이분법을 사용하여 최솟값을 정한다.
'''
1. 아이디어
- 우선 1~N까지 도달하는지 파악
- 연결 될 때 마다 비용을 따로 저장
2. 시간 복잡도
- ElogN
3. 변수
edge = [][]
distance = []
'''

import sys
import heapq
input = sys.stdin.readline

INF = sys.maxsize
n, p, k = map(int, input().split())
edge = [[] for _ in range(n+1)]
for _ in range(p):
    a, b, w = map(int, input().split())
    edge[a].append((w, b))
    edge[b].append((w, a))


def dijkstra(start):
    dist = [INF] * (n+1)
    dist[1] = 0
    heap = [(0, start)]
    while heap:
        ew, ev = heapq.heappop(heap)
        if dist[ev] < ew : continue
        for nw, nv in edge[ev]:
            if nw > mid:
                if dist[nv] > 1 + ew:
                    dist[nv] = 1 + ew
                    heapq.heappush(heap, (1+ew, nv))
            else:
                if dist[nv] > ew:
                    dist[nv] = ew
                    heapq.heappush(heap, (ew, nv))
    return dist

start, end, answer = 0, 1000001, 1000001
while start <= end:
    mid = (start + end) // 2
    result  = dijkstra(1)

    if result[n] > k:
        start = mid + 1
    elif result[n] <= k:
        answer = mid
        end = mid- 1

print( -1 if answer == 1000001 else answer)
728x90
LIST
Comments