์•Œ๊ณ ๋ฆฌ์ฆ˜

์ตœ๋‹จ ๊ฒฝ๋กœ ์•Œ๊ณ ๋ฆฌ์ฆ˜(๋‹ค์ต์ŠคํŠธ๋ผ, ํ”Œ๋กœ์ด๋“œ-์›Œ์…œ)

alswlfl 2026. 4. 5. 00:09

์ตœ๋‹จ ๊ฒฝ๋กœ ์•Œ๊ณ ๋ฆฌ์ฆ˜

๊ฐ€์žฅ ์งง์€ ๊ฒฝ๋กœ๋ฅผ ์ฐพ๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜

  • ๊ฐ ์ง€์ ์€ ๊ทธ๋ž˜ํ”„์—์„œ ๋…ธ๋“œ๋กœ ํ‘œํ˜„
  • ์ง€์  ๊ฐ„ ์—ฐ๊ฒฐ๋œ ๋„๋กœ๋Š” ๊ทธ๋ž˜ํ”„์—์„œ ๊ฐ„์„ ์œผ๋กœ ํ‘œํ˜„

๋‹ค์–‘ํ•œ ๋ฌธ์ œ ์ƒํ™ฉ

  • ํ•œ ์ง€์ ์—์„œ ๋‹ค๋ฅธ ํ•œ ์ง€์ ๊นŒ์ง€์˜ ์ตœ๋‹จ ๊ฒฝ๋กœ → BFS ์ด์šฉ
  • ํ•œ ์ง€์ ์—์„œ ๋‹ค๋ฅธ ๋ชจ๋“  ์ง€์ ๊นŒ์ง€์˜ ์ตœ๋‹จ ๊ฒฝ๋กœ → ๋‹ค์ต์ŠคํŠธ๋ผ ์•Œ๊ณ ๋ฆฌ์ฆ˜
  • ๋ชจ๋“  ์ง€์ ์—์„œ ๋‹ค๋ฅธ ๋ชจ๋“  ์ง€์ ๊นŒ์ง€์˜ ์ตœ๋‹จ ๊ฒฝ๋กœ → ํ”Œ๋กœ์ด๋“œ ์›Œ์…œ ์•Œ๊ณ ๋ฆฌ์ฆ˜

์ตœ๋‹จ ๊ฒฝ๋กœ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๋™์ž‘ ๊ณผ์ •

  1. ์ตœ๋‹จ ๊ฑฐ๋ฆฌ ํ…Œ์ด๋ธ”์€ ๊ฐ ๋…ธ๋“œ์— ๋Œ€ํ•œ ํ˜„์žฌ๊นŒ์ง€์˜ ์ตœ๋‹จ ๊ฑฐ๋ฆฌ ์ •๋ณด๋ฅผ ๊ฐ€์ง„๋‹ค.
  2. ์ฒ˜๋ฆฌ ๊ณผ์ •์—์„œ ๋” ์งง์€ ๊ฒฝ๋กœ๋ฅผ ์ฐพ์œผ๋ฉด ๋” ์งง์€ ๊ฒฝ๋กœ๋กœ ๊ฐ’์„ ๊ฐฑ์‹ 

 

๋‹ค์ต์ŠคํŠธ๋ผ ์•Œ๊ณ ๋ฆฌ์ฆ˜

  • ํŠน์ •ํ•œ ๋…ธ๋“œ์—์„œ ์ถœ๋ฐœํ•ด์„œ ๋‹ค๋ฅธ ๋ชจ๋“  ๋…ธ๋“œ๋กœ ๊ฐ€๋Š” ์ตœ๋‹จ ๊ฒฝ๋กœ ๊ณ„์‚ฐ
  • ๋‹ค์ต์ŠคํŠธ๋ผ ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ์Œ์˜ ๊ฐ„์„ ์ด ์—†์„ ๋•Œ ์ •์ƒ์ ์œผ๋กœ ๋™์ž‘
    - ํ˜„์‹ค ์„ธ๊ณ„์˜ ๊ฐ„์„ ์€ ์Œ์˜ ๊ฐ„์„ ์œผ๋กœ ํ‘œํ˜„X
    - ์Œ์˜ ๊ฐ„์„ ์ด ํฌํ•จ๋  ๋•Œ๋Š” ๋ฒจ๋งŒ ํฌ๋“œ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์‚ฌ์šฉ
  • ๊ทธ๋ฆฌ๋”” ์•Œ๊ณ ๋ฆฌ์ฆ˜์œผ๋กœ ๋ถ„๋ฅ˜๋จ → ๋งค ์ƒํ™ฉ์—์„œ ๊ฐ€์žฅ ๋น„์šฉ์ด ์ ์€ ๋…ธ๋“œ๋ฅผ ์„ ํƒํ•ด ์ž„์˜์˜ ๊ณผ์ • ๋ฐ˜๋ณต
  • ์‹œ๊ฐ„ ๋ณต์žก๋„: O(ElogV)
    - ๋…ธ๋“œ ํ•˜๋‚˜์”ฉ ๊บผ๋‚ด ๊ฒ€์‚ฌํ•˜๋Š” ๋ฐ˜๋ณต๋ฌธ์€ ๋…ธ๋“œ์˜ ๊ฐœ์ˆ˜ V ์ด์ƒ์˜ ํšŸ์ˆ˜๋กœ ์ฒ˜๋ฆฌX
    - E๊ฐœ์˜ ์›์†Œ๋ฅผ ์šฐ์„ ์ˆœ์œ„ ํ์— ๋„ฃ์—ˆ๋‹ค๊ฐ€ ๋ชจ๋‘ ๋นผ๋‚ด๋Š” ์—ฐ์‚ฐ๊ณผ ๋งค์šฐ ์œ ์‚ฌ

๋™์ž‘ ๊ณผ์ •

  1. ์ถœ๋ฐœ ๋…ธ๋“œ ์„ค์ •
  2. ์ตœ๋‹จ ๊ฑฐ๋ฆฌ ํ…Œ์ด๋ธ” ์ดˆ๊ธฐํ™”
  3. ๋ฐฉ๋ฌธํ•˜์ง€ ์•Š์€ ๋…ธ๋“œ ์ค‘์—์„œ ์ตœ๋‹จ ๊ฑฐ๋ฆฌ๊ฐ€ ๊ฐ€์žฅ ์งง์€ ๋…ธ๋“œ ์„ ํƒ
  4. ํ•ด๋‹น ๋…ธ๋“œ๋ฅผ ๊ฑฐ์ณ ๋‹ค๋ฅธ ๋…ธ๋“œ๋กœ ๊ฐ€๋Š” ๋น„์šฉ ๊ณ„์‚ฐํ•ด์„œ ์ตœ๋‹จ ๊ฑฐ๋ฆฌ ํ…Œ์ด๋ธ” ๊ฐฑ์‹ 
    - ์ตœ๋‹จ ๊ฑฐ๋ฆฌ ํ…Œ์ด๋ธ”์„ ์ง์ ‘ ๊ฐฑ์‹ ํ•˜์ง€ ์•Š๊ณ , ์šฐ์„ ์ˆœ์œ„ ํ์— ์‚ฝ์ž…ํ•˜๋Š” ๋ฐฉ์‹ ์‚ฌ์šฉ
  5. ์œ„ ๊ณผ์ •์—์„œ 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);
        }
    }
}