배달
1번 node 에서 모든 node 로 이동할 때, cost K 보다 적게 이동할 수 있는 마을의 갯수를 구하는 문제이다.
한 점(1) 에서 모든 점으로 가는 cost 를 구하는 문제이며, cost 는 양수이므로 다익스트라 이다.
풀이
코드 구조
- 갈 수 있는 node 를 먼저 구한다. (candidates)
- 그리고 그 node 까지 갈 수 있는 path 들을 모두 구한다. (pq). 그리고 거기서 최단거리만을 뽑아 계산한다.
코드
let totalCost;
let adjacent;
let N;
function solution(n, roads, K) {
N = n;
totalCost = new Array(n);
adjacent = new Array(n);
// Infinity 로 초기화
totalCost.fill(Infinity);
for (let i = 0; i < N; i++) {
adjacent[i] = new Array(N);
adjacent[i].fill(Infinity);
}
// adjacent 만들어둠
for (let i = 0; i < roads.length; i++) {
const [start, dest, c] = roads[i];
const minC = Math.min(adjacent[start - 1][dest - 1], adjacent[dest - 1][start - 1], c);
adjacent[start - 1][dest - 1] = minC; // 양방향의 cost가 같음
adjacent[dest - 1][start - 1] = minC; // 양방향의 cost가 같음
}
find();
return totalCost.filter((cost) => cost <= K).length;
}
function isPossible(path, i, adj, totalCost) {
if(adj[path][i] < Infinity) {
if(totalCost[i] > totalCost[path] + adj[path][i]) {
return true;
}
}
return false;
}
function find() {
const candidates = [];
const pq = new PriorityQueue();
// 0 에서 갈 수 있는 지점에 대해서 candidates 초기화
const startTown = 0;
totalCost[startTown] = 0;
for (let i = 0; i < N; i++) {
if (adjacent[startTown][i] < Infinity) {
totalCost[i] = adjacent[startTown][i];
candidates.push(i); // 여기서는 q 써도 됨, 한 점 (0) 에서 다른 점 I 로 갈 수 있는 길은 하나만 있기 때문
}
}
while (candidates.length > 0) {
// [어떤 점 (node)] 에서 한 depth 에서 갈 수 있는 모든 [path 와 거기까지 가는데 걸리는 cost] 를 [구하기만] 한다. (가지 않는다. 구하기만 한다.)
while (candidates.length > 0) {
const node = candidates.pop();
for (let i = 0; i < N; i++) {
if (isPossible(node, i, adjacent, totalCost)) { // node -> i 로 가도 되는지 체크
const accCost = totalCost[node] + adjacent[node][i];
const item = new Item(i, accCost);
pq.push(item);
}
}
}
const visit = new Set(); // 방문 체크용으로 쓰는 변수
// 위에서 구해둔 [갈 수 있는 path] 들 중에서 [최소한의 cost 를 갖는 path] 를 구한다.
while (pq.length() > 0) {
const {path, cost} = pq.pop();
if(!visit.has(path)) { // visit 했는지 check, 안했다면 방문함
visit.add(path);
totalCost[path] = cost; // updateTotalCost
candidates.push(path);
}
}
}
}
우선순위 큐 코드
더보기
function Item(path, cost) {
this.path = path;
this.cost = cost;
}
function PriorityQueue() {
this.array = [];
}
PriorityQueue.prototype.pop = function () {
this.array.sort(function (item1, item2) {
return item2.cost - item1.cost;
});
return this.array.pop();
}
PriorityQueue.prototype.push = function (item) {
this.array.push(item);
}
PriorityQueue.prototype.length = function () {
return this.array.length;
}
PriorityQueue.prototype.print = function () {
let ret = "";
for (let i = 0; i < this.array.length; i++) {
const {path, cost} = this.array[i];
ret += alpha[path] + "/" + cost + "...";
}
console.log(ret);
}
'알고리즘 Algorithm' 카테고리의 다른 글
[프로그래머스] Lv.3 가장 먼 노드 (BFS) + 시간초과, 메모리초과 해결 (0) | 2023.02.25 |
---|---|
[프로그래머스] Lv.2 게임 맵 최단거리 (BFS) + 반례 14개, 연습용 좌표판 PDF (2) | 2023.02.03 |
[프로그래머스] Lv.2 N-queen (DFS) + 연습용 체스판 (0) | 2023.01.20 |
[프로그래머스] Lv.2 모음사전 (완전탐색) (0) | 2023.01.16 |