오늘 팀전을 다들 열심히 하시는 것을 보고 원장선생님은 세미나 실에 인터넷을 설치해 주기로 마음을 먹으셨다. 하지만 비 협조적인 코레스코 콘도는 원장님께서 학생들에게 인터넷 선을 연결하는 것에 대해서 일부에 대해 돈을 요구하였다.
각각의 학생들의 번호가 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을 출력한다.
5 7 1
1 2 5
3 1 4
2 4 8
3 2 3
5 2 9
3 4 7
4 5 6
4
이 문제는 이분탐색과 다익스트라 알고리즘을 이용해서 풀 수 있었다. 이분탐색을 이용한 결정을 생각해내기 어려울 수 있다.
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.PriorityQueue;
public class Main {
static ArrayList<Pair>[] map;
public static void main(String[] args) throws Exception{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] input = br.readLine().split(" ");
int N = Integer.parseInt(input[0]);
int P = Integer.parseInt(input[1]);
int K = Integer.parseInt(input[2]);
int left = 0;
int right = 0;
int ans = -1;
map = new ArrayList[N+1];
for(int i=1; i<=N; i++)
map[i] = new ArrayList<>();
for(int i=0; i<P; i++) {
input = br.readLine().split(" ");
int start = Integer.parseInt(input[0]);
int end = Integer.parseInt(input[1]);
int cost = Integer.parseInt(input[2]);
map[start].add(new Pair(end, cost));
map[end].add(new Pair(start, cost));
right = Math.max(right, cost);
}
while(left<=right) {
int mid = (left+right)/2;
if(dijkstra(N, K, mid)) {
right = mid-1;
ans = mid;
}
else
left = mid+1;
}
System.out.println(ans);
}
public static boolean dijkstra(int N, int K, int max) {
PriorityQueue<Pair> pq = new PriorityQueue<>();
int[] dist = new int[N+1];
for(int i=1; i<=N; i++)
dist[i] = Integer.MAX_VALUE;
dist[1] = 0;
pq.add(new Pair(1, 0));
while(!pq.isEmpty()) {
Pair temp = pq.poll();
for (int i=0; i<map[temp.end].size(); i++) {
Pair next = map[temp.end].get(i);
if (dist[next.end] > temp.cost+(next.cost > max ? 1 : 0)) {
dist[next.end] = temp.cost+(next.cost > max ? 1 : 0);
pq.add(new Pair(next.end, dist[next.end]));
}
}
}
return dist[N]<=K;
}
public static class Pair implements Comparable<Pair>{
int end;
int cost;
public Pair(int end, int cost) {
this.end = end;
this.cost = cost;
}
public int compareTo(Pair p) {
return this.cost > p.cost ? 1 : -1;
}
}
}