๐Ÿ“ algorithm

[๋ฐฑ์ค€] ์ตœ์†Œ๋น„์šฉ ๊ตฌํ•˜๊ธฐ

c0zi 2025. 2. 13. 14:33

๐Ÿ’™ ๋ฌธ์ œ ์„ค๋ช…

 

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];
}