[๋ฐฑ์ค] ์ต์๋น์ฉ ๊ตฌํ๊ธฐ
๐ ๋ฌธ์ ์ค๋ช
N๊ฐ์ ๋์๊ฐ ์๋ค. ๊ทธ๋ฆฌ๊ณ ํ ๋์์์ ์ถ๋ฐํ์ฌ ๋ค๋ฅธ ๋์์ ๋์ฐฉํ๋ M๊ฐ์ ๋ฒ์ค๊ฐ ์๋ค. ์ฐ๋ฆฌ๋ A๋ฒ์งธ ๋์์์ B๋ฒ์งธ ๋์๊น์ง ๊ฐ๋๋ฐ ๋๋ ๋ฒ์ค ๋น์ฉ์ ์ต์ํ ์ํค๋ ค๊ณ ํ๋ค. A๋ฒ์งธ ๋์์์ B๋ฒ์งธ ๋์๊น์ง ๊ฐ๋๋ฐ ๋๋ ์ต์๋น์ฉ์ ์ถ๋ ฅํ์ฌ๋ผ. ๋์์ ๋ฒํธ๋ 1๋ถํฐ N๊น์ง์ด๋ค.
๐ ์ ๋ ฅ
์ฒซ์งธ ์ค์ ๋์์ ๊ฐ์ N(1 ≤ N ≤ 1,000)์ด ์ฃผ์ด์ง๊ณ ๋์งธ ์ค์๋ ๋ฒ์ค์ ๊ฐ์ M(1 ≤ M ≤ 100,000)์ด ์ฃผ์ด์ง๋ค. ๊ทธ๋ฆฌ๊ณ ์ ์งธ ์ค๋ถํฐ M+2์ค๊น์ง ๋ค์๊ณผ ๊ฐ์ ๋ฒ์ค์ ์ ๋ณด๊ฐ ์ฃผ์ด์ง๋ค. ๋จผ์ ์ฒ์์๋ ๊ทธ ๋ฒ์ค์ ์ถ๋ฐ ๋์์ ๋ฒํธ๊ฐ ์ฃผ์ด์ง๋ค. ๊ทธ๋ฆฌ๊ณ ๊ทธ ๋ค์์๋ ๋์ฐฉ์ง์ ๋์ ๋ฒํธ๊ฐ ์ฃผ์ด์ง๊ณ ๋ ๊ทธ ๋ฒ์ค ๋น์ฉ์ด ์ฃผ์ด์ง๋ค. ๋ฒ์ค ๋น์ฉ์ 0๋ณด๋ค ํฌ๊ฑฐ๋ ๊ฐ๊ณ , 100,000๋ณด๋ค ์์ ์ ์์ด๋ค.
๊ทธ๋ฆฌ๊ณ M+3์งธ ์ค์๋ ์ฐ๋ฆฌ๊ฐ ๊ตฌํ๊ณ ์ ํ๋ ๊ตฌ๊ฐ ์ถ๋ฐ์ ์ ๋์๋ฒํธ์ ๋์ฐฉ์ ์ ๋์๋ฒํธ๊ฐ ์ฃผ์ด์ง๋ค. ์ถ๋ฐ์ ์์ ๋์ฐฉ์ ์ ๊ฐ ์ ์๋ ๊ฒฝ์ฐ๋ง ์ ๋ ฅ์ผ๋ก ์ฃผ์ด์ง๋ค.
๐ ์ถ๋ ฅ
์ฒซ์งธ ์ค์ ์ถ๋ฐ ๋์์์ ๋์ฐฉ ๋์๊น์ง ๊ฐ๋๋ฐ ๋๋ ์ต์ ๋น์ฉ์ ์ถ๋ ฅํ๋ค.
๐ซ ์ ํ์ฌํญ
- 1 ≤ N ≤ 1,000
- 1 ≤ M ≤ 100,000
- ์๊ฐ์ ํ : 0.5 s
โค๏ธ ๋ฌธ์ ํ์ด ๋ฐฉ๋ฒ
1๏ธโฃ ๋ค์ต์คํธ๋ผ
์ต์ ๋น์ฉ (์ต๋จ ๊ฑฐ๋ฆฌ)๋๊น ๋ฐ๋ก ๋ค์ต์คํธ๋ผ๋ฅผ ๋ ์ฌ๋ฆด ์ ์๋ค.
๊ทธ๋ฐ๋ฐ ๋ฌธ์ ๋, js๋ ์ฐ์ ์์ ํ ๊ตฌํ์ฒด๊ฐ ์๋ค. ๊ทธ๋์ ๋ค์ต์คํธ๋ผ ์๊ณ ๋ฆฌ์ฆ ๋ฌธ์ ๋ฅผ ํญ์ ๋ฏธ๋ค์๋๋ฐ ๋๋์ด ๊ณต๋ถ๋ฅผ ํ๋ค.
์ฐ์ ๋ช๊ฐ์ง ์ต์ํ ๊ตฌํ ์๊ณ ๋ฆฌ์ฆ๋ค์ ์ฐพ์๋ณด๋ค๊ฐ ์ง๊ด์ ์ด๊ณ ์ ์ธ์์ง๋ ์ฝ๋ ๊ฐ์ง๊ณ ์ดํดํ๋ฉด์ ์ธ์ ๋ค.
์ฐ์ ์์ ํ๋ฅผ ๊ตฌํํ๊ณ , ์ด๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๋ค์ต์คํธ๋ผ ์๊ณ ๋ฆฌ์ฆ์ ์ฌ์ฉํ๋ค.
์ต์ํ์ด ๋ค ๋น ๋๊น์ง ๋ ธ๋๋ฅผ ๊บผ๋ด๊ณ , ํด๋น ์์น๊น์ง ์ ์ฅ๋ ํ์ฌ ๋น์ฉ๋ณด๋ค ํ์์ ๊บผ๋ธ ๋ ธ๋ ๊ฐ์ ์ ๋น์ฉ์ด ๋ ์ ์ผ๋ฉด ๊ฐฑ์ ํ๋ ๋ก์ง์ด๋ค.
์๊ฐ๋ณด๋ค ์ต์ํ ์๊ณ ๋ฆฌ์ฆ์ ์ธ์ฐ๋ค๋ณด๋, ๋ค์ต์คํธ๋ผ๋ ๊ธ๋ฐฉ ๊ตฌํํ ์ ์์๋ค. ๊ณจ๋5๋ผ ๊ทธ๋ฐ๊ฐ ..
์๊ฐ์ 532ms ๊ฑธ๋ ธ๋ค.
class MinHeap {
constructor() {
this.heap = [];
}
insert(edge, cost) {
const node = { edge, cost };
this.heap.push(node);
this.upHeap();
}
upHeap() {
const heap = this.heap;
let idx = heap.length - 1;
const node = heap[idx];
while (idx > 0) {
let parentIdx = Math.floor((idx - 1) / 2);
if (heap[parentIdx].cost <= heap[idx].cost) break;
heap[idx] = heap[parentIdx];
idx = parentIdx;
}
heap[idx] = node;
}
remove() {
const heap = this.heap;
if (heap.length === 0) return undefined;
if (heap.length === 1) return heap.pop();
const min = heap[0];
heap[0] = heap.pop();
this.downHeap();
return min;
}
downHeap() {
const heap = this.heap;
const length = heap.length;
let idx = 0;
const node = heap[idx];
while (idx * 2 + 1 < length) {
let leftIdx = idx * 2 + 1;
let rightIdx = leftIdx + 1;
let smallerChildIdx = leftIdx;
if (rightIdx < length && heap[rightIdx].cost < heap[leftIdx].cost)
smallerChildIdx = rightIdx;
heap[idx] = heap[smallerChildIdx];
idx = smallerChildIdx;
}
heap[idx] = node;
}
isEmpty() {
return this.heap.length === 0;
}
}
// ์
๋ ฅ ๋ณ์ ์ฒ๋ฆฌ
const fs = require("fs");
const [[n], [m], ...rest] = fs
.readFileSync(0, "utf-8")
.trim()
.split("\n")
.map((line) => line.split(" ").map(Number));
const edgeInfo = rest.slice(0, m);
const [[startIdx, endIdx]] = rest.slice(m);
const adjList = Array.from({ length: n }, () => []);
const minCost = Array.from({ length: n }, () => Infinity);
for ([start, end, cost] of edgeInfo) {
adjList[start - 1].push({ edge: end - 1, cost });
}
console.log(dijkstra(startIdx - 1, endIdx - 1));
function dijkstra(start, end) {
const minHeap = new MinHeap();
minHeap.insert(start, 0);
minCost[start] = 0;
while (!minHeap.isEmpty()) {
const node = minHeap.remove();
// ์ด๋ฏธ ๋ ์์ ๊ฐ์ด ์ ์ฅ๋์ด ์์ผ๋ฉด ๋์ด๊ฐ๊ธฐ
if (node.cost > minCost[node.edge]) continue;
for (let { edge, cost } of adjList[node.edge]) {
let newCost = cost + node.cost;
if (newCost < minCost[edge]) {
minCost[edge] = newCost;
minHeap.insert(edge, newCost);
}
}
}
return minCost[end];
}