์๊ณ ๋ฆฌ์ฆ
์ต๋จ ๊ฒฝ๋ก ์๊ณ ๋ฆฌ์ฆ(๋ค์ต์คํธ๋ผ, ํ๋ก์ด๋-์์ )
alswlfl
2026. 4. 5. 00:09
์ต๋จ ๊ฒฝ๋ก ์๊ณ ๋ฆฌ์ฆ
๊ฐ์ฅ ์งง์ ๊ฒฝ๋ก๋ฅผ ์ฐพ๋ ์๊ณ ๋ฆฌ์ฆ
- ๊ฐ ์ง์ ์ ๊ทธ๋ํ์์ ๋ ธ๋๋ก ํํ
- ์ง์ ๊ฐ ์ฐ๊ฒฐ๋ ๋๋ก๋ ๊ทธ๋ํ์์ ๊ฐ์ ์ผ๋ก ํํ
๋ค์ํ ๋ฌธ์ ์ํฉ
- ํ ์ง์ ์์ ๋ค๋ฅธ ํ ์ง์ ๊น์ง์ ์ต๋จ ๊ฒฝ๋ก → BFS ์ด์ฉ
- ํ ์ง์ ์์ ๋ค๋ฅธ ๋ชจ๋ ์ง์ ๊น์ง์ ์ต๋จ ๊ฒฝ๋ก → ๋ค์ต์คํธ๋ผ ์๊ณ ๋ฆฌ์ฆ
- ๋ชจ๋ ์ง์ ์์ ๋ค๋ฅธ ๋ชจ๋ ์ง์ ๊น์ง์ ์ต๋จ ๊ฒฝ๋ก → ํ๋ก์ด๋ ์์ ์๊ณ ๋ฆฌ์ฆ
์ต๋จ ๊ฒฝ๋ก ์๊ณ ๋ฆฌ์ฆ ๋์ ๊ณผ์
- ์ต๋จ ๊ฑฐ๋ฆฌ ํ ์ด๋ธ์ ๊ฐ ๋ ธ๋์ ๋ํ ํ์ฌ๊น์ง์ ์ต๋จ ๊ฑฐ๋ฆฌ ์ ๋ณด๋ฅผ ๊ฐ์ง๋ค.
- ์ฒ๋ฆฌ ๊ณผ์ ์์ ๋ ์งง์ ๊ฒฝ๋ก๋ฅผ ์ฐพ์ผ๋ฉด ๋ ์งง์ ๊ฒฝ๋ก๋ก ๊ฐ์ ๊ฐฑ์
๋ค์ต์คํธ๋ผ ์๊ณ ๋ฆฌ์ฆ
- ํน์ ํ ๋ ธ๋์์ ์ถ๋ฐํด์ ๋ค๋ฅธ ๋ชจ๋ ๋ ธ๋๋ก ๊ฐ๋ ์ต๋จ ๊ฒฝ๋ก ๊ณ์ฐ
- ๋ค์ต์คํธ๋ผ ์๊ณ ๋ฆฌ์ฆ์ ์์ ๊ฐ์ ์ด ์์ ๋ ์ ์์ ์ผ๋ก ๋์
- ํ์ค ์ธ๊ณ์ ๊ฐ์ ์ ์์ ๊ฐ์ ์ผ๋ก ํํX
- ์์ ๊ฐ์ ์ด ํฌํจ๋ ๋๋ ๋ฒจ๋ง ํฌ๋ ์๊ณ ๋ฆฌ์ฆ ์ฌ์ฉ - ๊ทธ๋ฆฌ๋ ์๊ณ ๋ฆฌ์ฆ์ผ๋ก ๋ถ๋ฅ๋จ → ๋งค ์ํฉ์์ ๊ฐ์ฅ ๋น์ฉ์ด ์ ์ ๋ ธ๋๋ฅผ ์ ํํด ์์์ ๊ณผ์ ๋ฐ๋ณต
- ์๊ฐ ๋ณต์ก๋: O(ElogV)
- ๋ ธ๋ ํ๋์ฉ ๊บผ๋ด ๊ฒ์ฌํ๋ ๋ฐ๋ณต๋ฌธ์ ๋ ธ๋์ ๊ฐ์ V ์ด์์ ํ์๋ก ์ฒ๋ฆฌX
- E๊ฐ์ ์์๋ฅผ ์ฐ์ ์์ ํ์ ๋ฃ์๋ค๊ฐ ๋ชจ๋ ๋นผ๋ด๋ ์ฐ์ฐ๊ณผ ๋งค์ฐ ์ ์ฌ
๋์ ๊ณผ์
- ์ถ๋ฐ ๋ ธ๋ ์ค์
- ์ต๋จ ๊ฑฐ๋ฆฌ ํ ์ด๋ธ ์ด๊ธฐํ
- ๋ฐฉ๋ฌธํ์ง ์์ ๋ ธ๋ ์ค์์ ์ต๋จ ๊ฑฐ๋ฆฌ๊ฐ ๊ฐ์ฅ ์งง์ ๋ ธ๋ ์ ํ
- ํด๋น ๋
ธ๋๋ฅผ ๊ฑฐ์ณ ๋ค๋ฅธ ๋
ธ๋๋ก ๊ฐ๋ ๋น์ฉ ๊ณ์ฐํด์ ์ต๋จ ๊ฑฐ๋ฆฌ ํ
์ด๋ธ ๊ฐฑ์
- ์ต๋จ ๊ฑฐ๋ฆฌ ํ ์ด๋ธ์ ์ง์ ๊ฐฑ์ ํ์ง ์๊ณ , ์ฐ์ ์์ ํ์ ์ฝ์ ํ๋ ๋ฐฉ์ ์ฌ์ฉ - ์ ๊ณผ์ ์์ 3๋ฒ๊ณผ 4๋ฒ ๋ฐ๋ณต
์ฐ์ ์์ ํ: ์ฐ์ ์์๊ฐ ๊ฐ์ฅ ๋์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ฅ ๋จผ์ ์ญ์ ํ๋ ์๋ฃ๊ตฌ์กฐ
- ํ ์ด์ฉํด์ ๊ตฌํ
1) ์ต์ ํ: ๋ถ๋ชจ ๋ ธ๋๋ ํญ์ ์์ ๋ ธ๋๋ณด๋ค ๊ฐ์ด ์์์ผ ํจ
2) ์ต๋ ํ: ๋ถ๋ชจ ๋ ธ๋๋ ํญ์ ์์ ๋ ธ๋๋ณด๋ค ํฌ๊ฑฐ๋ ๊ฐ์์ผ ํจ
- ์๊ฐ ๋ณต์ก๋: O(logN)
- JS์์๋ ์ฐ์ ์์ ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ ๊ณต X
ํน์ง
- ๋จ๊ณ๋ฅผ ๊ฑฐ์น๋ฉฐ ํ ๋ฒ ์ฒ๋ฆฌ๋ ๋ ธ๋์ ์ต๋จ ๊ฑฐ๋ฆฌ๋ ๊ณ ์ ๋์ด ๋ ์ด์ ๋ฐ๋์ง ์์
- ๋ค์ต์คํธ๋ผ ์๊ณ ๋ฆฌ์ฆ ์ํํ ๋ค์ ํ ์ด๋ธ์ ๊ฐ ๋ ธ๋๊น์ง์ ์ต๋จ ๊ฑฐ๋ฆฌ ์ ๋ณด๊ฐ ์ ์ฅ๋จ
- ๋จ๊ณ๋ง๋ค ๋ฐฉ๋ฌธํ์ง ์์ ๋ ธ๋ ์ค์์ ์ต๋จ ๊ฑฐ๋ฆฌ๊ฐ ๊ฐ์ฅ ์งง์ ๋ ธ๋ ์ ํ
์์ค ์ฝ๋ ์์
- ์ต์ ํ → ์ต๋๊ฐ ๊ตฌํ๊ธฐ
- ์ต๋ ํ → ์ต์๊ฐ ๊ตฌํ๊ธฐ
์ต์ ํ ๊ตฌํ

- ๋ถ๋ชจ ๋ ธ๋ ์ธ๋ฑ์ค = (์์ ๋ ธ๋ ์ธ๋ฑ์ค - 1) / 2
- ์ผ์ชฝ ์์ ๋ ธ๋ ์ธ๋ฑ์ค = (๋ถ๋ชจ ๋ ธ๋ ์ธ๋ฑ์ค*2) + 1
- ์ค๋ฅธ์ชฝ ์์ ๋ ธ๋ ์ธ๋ฑ์ค = (๋ถ๋ชจ ๋ ธ๋ ์ธ๋ฑ์ค*2) + 2
class PriorityQueue {
constructor() {
this.heap = []; // ์ต์ ํ
}
getParentIdx = (childIdx) => Math.floor((childIdx - 1) / 2);
getLeftChildIdx = (parentIdx) => parentIdx * 2 + 1;
getRightChildIdx = (parentIdx) => parentIdx * 2 + 2;
getLength = () => this.heap.length;
enqueue = (node, cost) => {
this.heap.push({ node: node, cost: cost }); // ๋ง์ง๋ง์ ์ ์์ ์ถ๊ฐ
let currentIdx = this.heap.length - 1; // ์ ์์ ์ธ๋ฑ์ค
while (currentIdx > 0) {
const parentIdx = this.getParentIdx(currentIdx);
if (cost >= this.heap[parentIdx].cost) break; // ์์ ๋
ธ๋๊ฐ ๋ ํฐ ๊ฒฝ์ฐ ํจ์ค
// ์์ ๋
ธ๋๊ฐ ๋ ์์ ๊ฒฝ์ฐ ์์น swap
[this.heap[parentIdx], this.heap[currentIdx]] = [this.heap[currentIdx], this.heap[parentIdx]];
currentIdx = parentIdx;
}
};
dequeue = () => {
if (this.getLength() === 0) return undefined;
else if (this.getLength() === 1) return this.heap.pop();
else {
const item = this.heap[0];
this.heap[0] = this.heap.pop(); // ๋ง์ง๋ง ์์ ๋ฃจํธ๋ก ์ด๋
let currentIdx = 0;
while (currentIdx < this.getLength()) {
const leftChildIdx = this.getLeftChildIdx(currentIdx);
const rightChildIdx = this.getRightChildIdx(currentIdx);
// ์ผ์ชฝ ์์๊ณผ ์ค๋ฅธ์ชฝ ์์ ์ค์ ๋ ์์ ์์๋ Swap
let nextIdx = currentIdx;
if (leftChildIdx < this.getLength() && this.heap[leftChildIdx].cost < this.heap[nextIdx].cost)
nextIdx = leftChildIdx;
if (rightChildIdx < this.getLength() && this.heap[rightChildIdx].cost < this.heap[nextIdx].cost)
nextIdx = rightChildIdx;
if (nextIdx === currentIdx) break; // ๋ถ๋ชจ ์์๊ฐ ๋ ์์ ๊ฒฝ์ฐ ์ค๋จ
[this.heap[nextIdx], this.heap[currentIdx]] = [this.heap[currentIdx], this.heap[nextIdx]];
currentIdx = nextIdx;
}
return item;
}
};
}
const fs = require('fs');
const input = fs.readFileSync('/dev/stdin').toString().split('\n');
const [V, E] = input[0].split(' ').map(Number); // ์ ์ : V, ๊ฐ์ : E
const K = +input[1]; // ์์ ์ ์ ๋ฒํธ
const graph = Array.from({ length: V + 1 }, () => []);
for (let i = 0; i < E; i++) {
const [u, v, w] = input[i + 2].split(' ').map(Number);
graph[u].push([v, w]);
}
const minCost = Array.from({ length: V + 1 }, () => Number.MAX_SAFE_INTEGER);
const pq = new PriorityQueue();
pq.enqueue(K, 0);
minCost[K] = 0; // ์์ ๋
ธ๋๋ 0์ผ๋ก ์ค์
while (pq.getLength() > 0) {
const { node, cost } = pq.dequeue();
for (const [next, value] of graph[node]) {
const newCost = cost + value;
if (minCost[next] <= newCost) continue;
pq.enqueue(next, newCost);
minCost[next] = newCost;
}
}
for (let c = 1; c <= V; c++) {
console.log(minCost[c] === Number.MAX_SAFE_INTEGER ? 'INF' : minCost[c]);
}
ํ๋ก์ด๋-์์ ์๊ณ ๋ฆฌ์ฆ
๋ชจ๋ ๋ ธ๋์์ ๋ค๋ฅธ ๋ชจ๋ ๋ ธ๋๊น์ง์ ์ต๋จ ๊ฒฝ๋ก ๋ชจ๋ ๊ณ์ฐ
- ํ ๋ฒ ์คํํ์ฌ ๋ชจ๋ ๋ ธ๋ ๊ฐ ์ต๋จ ๊ฒฝ๋ก๋ฅผ ๊ตฌํ ์ ์์. ๋ํ, ์์ ๊ฐ์ ๋ ์ฌ์ฉ ๊ฐ๋ฅ
- ๋งค ๋จ๊ณ๋ง๋ค ๋ฐฉ๋ฌธํ์ง ์์ ๋ ธ๋ ์ค์ ์ต๋จ ๊ฑฐ๋ฆฌ๋ฅผ ๊ฐ๋ ๋ ธ๋๋ฅผ ์ฐพ๋ ๊ณผ์ ํ์ X
- 2์ฐจ์ ํ ์ด๋ธ์ ์ต๋จ ๊ฑฐ๋ฆฌ ์ ๋ณด ์ ์ฅ
- DP ์ ํ์ ์ํจ
๋์ ๊ณผ์
- ๊ฐ ๋จ๊ณ๋ง๋ค ํน์ ํ ๋ ธ๋ K๋ฅผ ๊ฑฐ์ณ ๊ฐ๋ ๊ฒฝ์ฐ ํ์ธ → A์์ B๋ก ๊ฐ๋ ์ต๋จ ๊ฑฐ๋ฆฌ๋ณด๋ค A์์ K๋ฅผ ๊ฑฐ์ณ B๋ก ๊ฐ๋ ๊ฑฐ๋ฆฌ๊ฐ ๋ ์งง์์ง ๊ฒ์ฌ
- D[A][B] = MIN(D[A][B], D[A][K]+D[K][B])
์ฝ๋
const INF = Number.MAX_SAFE_INTEGER;
const N = 5; // ๋
ธ๋ ๊ฐ์
// graph[i][j]๋ i์์ j๋ก ๊ฐ๊ธฐ ์ํ ์ด๊ธฐ ๋น์ฉ(๊ฐ์ ๋น์ฉ)
// ์๊ธฐ ์์ ์ผ๋ก ๊ฐ๋ ๋น์ฉ์ 0์ผ๋ก ์ด๊ธฐํ
const graph = [
[INF, INF, INF, INF, INF, INF], // ์ธ๋ฑ์ค 0์ ์ฌ์ฉํ์ง ์์
[INF, 0, 1, 5, INF, INF], // 1๋ฒ ๋
ธ๋ ๊ฐ์ ๋ค
[INF, 7, 0, 2, 2, INF], // 2๋ฒ ๋
ธ๋ ๊ฐ์ ๋ค
[INF, 2, INF, 0, INF, 6], // 3๋ฒ ๋
ธ๋ ๊ฐ์ ๋ค
[INF, INF, 2, INF, 0, INF], // 4๋ฒ ๋
ธ๋ ๊ฐ์ ๋ค
[INF, INF, INF, 1, INF, 0], // 5๋ฒ ๋
ธ๋ ๊ฐ์ ๋ค
];
// ์ ํ์์ ๋ฐ๋ผ ํ๋ก์ด๋ ์์
์๊ณ ๋ฆฌ์ฆ ์ํ
for (let k = 1; k <= N; k++) {
for (let a = 1; a <= N; a++) {
for (let b = 1; b <= N; b++) {
const cost = graph[a][k] + graph[k][b];
graph[a][b] = Math.min(graph[a][b], cost);
}
}
}