문제
https://www.acmicpc.net/problem/1162
입출력
4 4 1
1 2 10
2 4 10
1 3 1
3 4 100
1
아이디어
다익스트라
+ (2차원 배열) 0로 만드는 것을 k번 사용할 수 있음
+ Long.compare()
+ 가지치기 (이미 거리가 너무 먼거 다시 큐에 넣지 않기)
코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.PriorityQueue;
import java.util.StringTokenizer;
public class Main {
static int N, M, K;
static List<Node>[] adj;
static long[][] dist;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken()); // 도시 수
M = Integer.parseInt(st.nextToken()); // 도로 수
K = Integer.parseInt(st.nextToken()); // 포장 가능 횟수
adj = new ArrayList[N + 1];
for (int i = 0; i <= N; i++) {
adj[i] = new ArrayList<>();
}
for (int r = 0; r < M; r++) {
st = new StringTokenizer(br.readLine());
int a = Integer.parseInt(st.nextToken());
int b = Integer.parseInt(st.nextToken());
int c = Integer.parseInt(st.nextToken()); // 거리
adj[a].add(new Node(b, c));
adj[b].add(new Node(a, c));
}
dist = new long[N + 1][K + 1];
for (int n = 0; n < N + 1; n++) {
Arrays.fill(dist[n], Long.MAX_VALUE); // Long 최대값으로 초기화
}
PriorityQueue<State> pq = new PriorityQueue<>();
pq.add(new State(1, 0, 0));
dist[1][0] = 0;
while (!pq.isEmpty()) {
State now = pq.poll();
if (now.dist > dist[now.nodeId][now.usedK]) // 가능성 없는 경우 사전에 가지치기
continue;
for (Node next : adj[now.nodeId]) {
// 도로 포장 안함
if (dist[next.to][now.usedK] > now.dist + next.dist) {
dist[next.to][now.usedK] = now.dist + next.dist;
pq.add(new State(next.to, now.usedK, dist[next.to][now.usedK])); // 지금까지의 거리 + 다음까지의 거리
}
// 도로 포장 함
if (now.usedK < K && dist[next.to][now.usedK + 1] > now.dist) {// 현재 -> 다음 (다음상태 : usedK + 1)
dist[next.to][now.usedK + 1] = now.dist;
pq.add(new State(next.to, now.usedK + 1, dist[next.to][now.usedK + 1]));
}
}
}
long minCost = Long.MAX_VALUE;
int minK = 0;
for (int i = 0; i <= K; i++) {
if (dist[N][i] < minCost) {
minCost = dist[N][i];
minK = i;
}
}
System.out.println(minCost);
}
static class State implements Comparable<State> {
int nodeId, usedK;
long dist;
State(int nodeId, int usedK, long dist) {
this.nodeId = nodeId;
this.usedK = usedK;
this.dist = dist;
}
@Override
public int compareTo(State o) {
return Long.compare(this.dist, o.dist); // Long 정렬 방식
}
}
static class Node {
int to, dist;
Node(int to, int dist) {
this.to = to;
this.dist = dist;
}
}
}
'Java' 카테고리의 다른 글
GCD, LCM 구하기 : 유클레드 호제법, a*b / gcd(a,b) (0) | 2025.03.30 |
---|---|
[코드트리] 경험치를 빠르게 얻기 (0) | 2025.03.29 |
[프로그래머스] 연속된 부분 수열의 합 (0) | 2025.03.26 |
[프로그래머스] 징검다리 건너기 (0) | 2025.03.25 |
[백준] 퇴사2 (0) | 2025.03.24 |