코딩테스트/다익스트라
[실버1] 백준 1149 RGB 거리 다익스트라 풀이(Java)
정재익
2025. 7. 25. 00:26
DP로 푸는게 빠르고 편하지만 다익스트라로도 풀 수 있다.
package org.practice.다익스트라;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
// 실버 1 RGB거리
// 한 마디로 양 옆에 집이랑 색깔이 같으면 안된다는 것 양 끝 집은 옆 집이랑만 비교하고
// 색이 같으면 안된다는 것은 일종의 간선으로 표현할 수 있다. 입력에는 배열로 빨,초,파의 각 견적이 나와있는데
// 이것을 선택하는 것을 어떠한 배열에서 특정한 배열로만 이동 가능하다고 보면 코스트를 가진 노드로 표현할 수 있다.
// 최소 비용으로 목적지까지 가는 문제와 동일하며 우선순위 큐를 이용한 다익스트라 알고리즘을 활용하면 된다.
public class b1149 {
static int houseCount;
static int[][] cost; // cost[i][j] = i번째 집을 j색으로 칠할 때의 비용
static int[][] dist; // dist[i][j] = i번째 집을 j색으로 칠할 때까지의 최소 누적 비용
static boolean[][] visited; // visited[i][j] = i번째 집을 j색으로 칠했는지 여부
static class Node implements Comparable<Node> {
int house;
int color;
int cost;
public Node(int house, int color, int cost) {
this.house = house;
this.color = color;
this.cost = cost;
}
@Override
public int compareTo(Node o) {
return Integer.compare(this.cost, o.cost);
}
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
houseCount = Integer.parseInt(br.readLine());
cost = new int[houseCount][3];
dist = new int[houseCount][3];
visited = new boolean[houseCount][3];
// 배열로 나타내면 다음열의 행이 같으면 안된다는 것이다.
// 하지만 시작 노드가 정해지지 않았다 그래도 3가지의 경우만 있으니 3가지를 비교하면 될 듯함.
for (int i = 0; i < houseCount; i++) {
StringTokenizer st = new StringTokenizer(br.readLine());
for (int j = 0; j < 3; j++) {
cost[i][j] = Integer.parseInt(st.nextToken());
dist[i][j] = Integer.MAX_VALUE; // 초기값 무한
}
}
dijkstra();
int result = Math.min(dist[houseCount - 1][0],
Math.min(dist[houseCount - 1][1], dist[houseCount - 1][2]));
System.out.println(result);
}
static void dijkstra() {
PriorityQueue<Node> pq = new PriorityQueue<>();
// 시작 노드: 첫 번째 집의 빨/초/파
for (int color = 0; color < 3; color++) {
dist[0][color] = cost[0][color];
pq.offer(new Node(0, color, dist[0][color]));
}
while (!pq.isEmpty()) {
Node curr = pq.poll();
int house = curr.house;
int color = curr.color;
if (visited[house][color]) continue;
visited[house][color] = true;
// 다음 집으로 이동
if (house + 1 < houseCount) {
for (int nextColor = 0; nextColor < 3; nextColor++) {
if (nextColor == color) continue; // 인접한 집은 같은 색 X
int nextCost = dist[house][color] + cost[house + 1][nextColor];
if (nextCost < dist[house + 1][nextColor]) {
dist[house + 1][nextColor] = nextCost;
pq.offer(new Node(house + 1, nextColor, nextCost));
}
}
}
}
}
}