N개의 마을로 이루어진 나라가 있습니다. 이 나라의 각 마을에는 1부터 N까지의 번호가 각각 하나씩 부여되어 있습니다. 각 마을은 양방향으로 통행할 수 있는 도로로 연결되어 있는데, 서로 다른 마을 간에 이동할 때는 이 도로를 지나야 합니다. 도로를 지날 때 걸리는 시간은 도로별로 다릅니다. 현재 1번 마을에 있는 음식점에서 각 마을로 음식 배달을 하려고 합니다. 각 마을로부터 음식 주문을 받으려고 하는데, N개의 마을 중에서 K 시간 이하로 배달이 가능한 마을에서만 주문을 받으려고 합니다. 다음은 N = 5, K = 3인 경우의 예시입니다.
위 그림에서 1번 마을에 있는 음식점은 [1, 2, 4, 5] 번 마을까지는 3 이하의 시간에 배달할 수 있습니다. 그러나 3번 마을까지는 3시간 이내로 배달할 수 있는 경로가 없으므로 3번 마을에서는 주문을 받지 않습니다. 따라서 1번 마을에 있는 음식점이 배달 주문을 받을 수 있는 마을은 4개가 됩니다.
마을의 개수 N, 각 마을을 연결하는 도로의 정보 road, 음식 배달이 가능한 시간 K가 매개변수로 주어질 때, 음식 주문을 받을 수 있는 마을의 개수를 return 하도록 solution 함수를 완성해주세요.
N | road | K | result |
---|---|---|---|
5 | [[1,2,1],[2,3,3],[5,2,2],[1,4,2],[5,3,1],[5,4,2]] | 3 | 4 |
6 | [[1,2,1],[1,3,2],[2,3,2],[3,4,3],[3,5,2],[3,5,3],[5,6,1]] | 4 | 4 |
다익스트라 알고리즘을 사용하여 각 마을별 최단시간을 구했다.
2차원 배열의 mapGraph
를 initMapGraph()
으로 초기화 해준다.
dijkstra()
에서 방문 마을을 표시할 visited
와 최소 방문 시간을 기록할 mintime
을 선언하고
mintime
은 0번째 인덱스 빼고 int의 최대값으로 초기화 해준다.
다음 방문 노드를 추가할 queue
를 선언하고 1번 마을을 추가해준다.
queue
가 비어있지 않다면 queue
에서 방문 마을 번호를 꺼내고 방문 표시를 해준다.
방문한 마을기준 mapGraph
를 탐색한다
0이 아닌 값이 존재한다면 mintime[i]
값과 mintime[townNum] + time
중 작은값을 갱신해준다.
다음 방문 마을은 방문하지 않은 마을중 가장 적은 시간이 걸리는 마을을 다음 마을로 queue
에 추가해준다.
모든 마을방문이 끝나면 mintime
에서 K 시간이내인 값 갯수를 세어 리턴해준다.
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
class Solution {
public int solution(int N, int[][] road, int K) {
int answer = 0;
int[][] mapGraph = new int[N][N]; // 마을 이동 시간 그래프
initMapGraph(road, mapGraph); // 마을 이동 시간 그래프 초기화
answer = dijkstra(mapGraph, N, K);
return answer;
}
private static void initMapGraph(int[][] road, int[][] mapGraph) {
for (int i = 0; i < road.length; i++) {
int town1 = road[i][0] - 1;
int town2 = road[i][1] - 1;
int time = road[i][2];
mapGraph[town1][town2] = mapGraph[town1][town2] > 0 && mapGraph[town1][town2] < time ? Math.min(time, mapGraph[town1][town2]) : time;
mapGraph[town2][town1] = mapGraph[town2][town1] > 0 && mapGraph[town2][town1] < time ? Math.min(time, mapGraph[town2][town1]) : time;
}
}
public static int dijkstra(int[][] mapGraph, int N, int K) {
int count = 0;
boolean[] visited = new boolean[N]; // 방문 마을 체크
int[] mintime = new int[N]; // 최소 방문 시간 기록
Arrays.fill(mintime, Integer.MAX_VALUE);
mintime[0] = 0;
Queue<Integer> queue = new LinkedList<>();
queue.add(1); // 1번마을 부터 시작
while (!queue.isEmpty()) {
int townNum = queue.poll() - 1;
visited[townNum] = true; // 방문
for (int i = 0; i < N; i++) {
int time = mapGraph[townNum][i]; //현재 마을에서 i마을 까지 이동 시간
if (time == 0) continue;
// 1번 마을에서 i 마을까지의 최소 이동 시간 갱신
mintime[i] = Math.min(mintime[townNum] + time, mintime[i]);
}
// 다음 방문 마을 정하기(방문 안한 마을중 가장 이동시간이 적은 곳)
int nextTown = Integer.MAX_VALUE;
int nextTownTime = Integer.MAX_VALUE;
for (int i = 0; i < visited.length; i++) {
if (!visited[i] && nextTownTime > mintime[i]) {
nextTownTime = mintime[i];
nextTown = i + 1;
}
}
if (nextTown != Integer.MAX_VALUE) queue.add(nextTown);
}
// K 시간 이내에 배달 가능한 마을 수 세기
for (int i = 0; i < mintime.length; i++) {
if (mintime[i] <= K) count++;
}
return count;
}
}