๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐Ÿง  ์•Œ๊ณ ๋ฆฌ์ฆ˜/์œ ํ˜•๋ณ„ ๋Œ€ํ‘œ๋ฌธ์ œ

[๋‹ค์ต์ŠคํŠธ๋ผ][๋ฐฑ์ค€] 117799 ์ตœ์†Œ๋น„์šฉ ๊ตฌํ•˜๊ธฐ2 JS

by megan07 2024. 1. 10.

๋ฌธ์ œ๋งํฌ

 

ํ•œ ๋…ธ๋“œ์—์„œ ๋‹ค๋ฅธ ๋…ธ๋“œ๊นŒ์ง€์˜ ์ตœ์†Œ ๋น„์šฉ์„ ๊ตฌํ•˜๋Š” ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— ๋‹ค์ต์ŠคํŠธ๋ผ!

 

๋‹ค์ต์ŠคํŠธ๋ผ : ํ•œ ์ •์ ์—์„œ ๋‹ค๋ฅธ ๋ชจ๋“  ์ •์ ๊นŒ์ง€์˜ ์ตœ์†Œ ๋น„์šฉ์„ ๊ตฌํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜

 

๋‹ค์ต์ŠคํŠธ๋ผ๋Š” ์šฐ์„ ์ˆœ์œ„ํ๋ฅผ ์‚ฌ์šฉํ•˜๋Š”๋ฐ

JS์—๋Š” ์šฐ์„ ์ˆœ์œ„ํ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์— ์ง์ ‘ ๊ตฌํ˜„

์ ‘๊ทผ ๋ฐฉ๋ฒ•
1. ๋ฒ„์Šค ์ •๋ณด ์ธ์ ‘๋ฆฌ์ŠคํŠธ, ๊ฐ ๋…ธ๋“œ๊นŒ์ง€์˜ ์ตœ์†Œ ๋น„์šฉ์„ ์ €์žฅํ•  ๋ฐฐ์—ด(minArr), ์ด์ „์— ๋ฐฉ๋ฌธํ•œ ๋…ธ๋“œ๋ฅผ ์ €์žฅํ•  ๋ฐฐ์—ด(pre)์„ ๋งŒ๋“ ๋‹ค.
2. ์šฐ์„ ์ˆœ์œ„ ํ์— ์‹œ์ž‘ ๋…ธ๋“œ๋ฅผ ๋„ฃ์–ด์ค€๋‹ค
3. ํ๊ฐ€ ๋นŒ ๋•Œ๊นŒ์ง€ ๋…ธ๋“œ๋ฅผ ๊บผ๋‚ด์„œ minArr์™€ pre๋ฐฐ์—ด์„ ์—…๋ฐ์ดํŠธ ํ•œ๋‹ค

3๋ฒˆ์—์„œ ๋ฐฐ์—ด๋“ค์„ ์—…๋ฐ์ดํŠธ ํ•  ๋•Œ
1. minArr์— ์žˆ๋Š” ๊ฐ’์ด ์šฐ์„ ์ˆœ์œ„ ํ์—์„œ ๊บผ๋‚ธ ๊ฐ’๋ณด๋‹ค ์ž‘์„ ๊ฒฝ์šฐ, ๊บผ๋‚ธ ๊ฐ’์€ ์ตœ์†Œ ๋น„์šฉ์ด ์•„๋‹˜์œผ๋กœ continue;
2. minArr์— ์žˆ๋Š” ๊ฐ’๋ณด๋‹ค ์šฐ์„ ์ˆœ์œ„ ํ์—์„œ ๊บผ๋‚ธ ๊ฐ’์ด ์ž‘์€ ๊ฒฝ์šฐ, ํ˜„์žฌ ๊ธฐ์ค€์—์„œ ์ œ์ผ ์ตœ์†Œ ๋น„์šฉ์ด๋ฏ€๋กœ minArr์˜ ๊ฐ’์„ ์—…๋ฐ์ดํŠธ ํ•ด์ค€๋‹ค.
๋˜ํ•œ ํ์—์„œ ๊บผ๋‚ธ ๋…ธ๋“œ๊ฐ€ ์ตœ์†Œ ๋น„์šฉ์ธ ์ƒํƒœ์ด๋ฏ€๋กœ ์ธ์ ‘ํ•œ ๋…ธ๋“œ๋“ค์˜ ๋น„์šฉ๋„ ํ™•์ธํ•ด์•ผ ํ•œ๋‹ค!
(ํ˜„์žฌ ๋…ธ๋“œ์˜ ๋น„์šฉ + ํ˜„์žฌ ๋…ธ๋“œ์—์„œ ์ธ์ ‘ ๋…ธ๋“œ๊นŒ์ง€์˜ ๋น„์šฉ)์„ minArr ๊ฐ’๊ณผ ๋น„๊ตํ•ด์„œ ๋” ์ž‘์€ ๊ฒฝ์šฐ์—๋Š” ์ธ์ ‘ ๋…ธ๋“œ์˜ minArr์™€ pre๋ฐฐ์—ด์„ ์—…๋ฐ์ดํŠธ ํ•˜๊ณ  ์šฐ์„ ์ˆœ์œ„ ํ์— ๋„ฃ์–ด์ค€๋‹ค.

 

 

 

 

 

ํ’€์ด ์ฝ”๋“œ

์šฐ์„ ์ˆœ์œ„ ํ ๊ตฌํ˜„ ์ฝ”๋“œ๋Š” ํŽ˜์ด์ง€ ๊ฐ€์žฅ ํ•˜๋‹จ์— ์žˆ์Šต๋‹ˆ๋‹ค!!


const filePath = process.platform === 'linux' ? '/dev/stdin' : './input.txt';

// ์ž…๋ ฅ๊ฐ’์ด ์ฒซ ๋ฒˆ์งธ ์ค„์—๋Š” ์ž…๋ ฅ ๊ฐ’์˜ ๊ธธ์ด(n), n๊ฐœ์˜ ์ค„์— ๊ฑธ์ณ์„œ ํ•œ ์ค„์— ํ•˜๋‚˜์˜ ์ž…๋ ฅ๊ฐ’์ด ์ฃผ์–ด์งˆ ๋•Œ
const [n, m, ...input] = require('fs')
  .readFileSync(filePath)
  .toString()
  .trim()
  .split('\n');

function solution(N, M, Routes, SE) {
  //์ตœ์†Œ๊ฐ’๋ฐฐ์—ด
  const minArr = new Array(N + 1).fill(Infinity);

  //๊ฒฝ๋กœ ํƒ์ƒ‰ - ์ด์ „ ๋…ธ๋“œ
  const pre = new Array(N + 1).fill(0);
  const pq = new PriorityQueue();
  const adjacencyList = {};
  const [start, end] = SE;
  const answerRoute = [];

  Routes.forEach(([start, end, weight]) => {
    if (!adjacencyList[start]) adjacencyList[start] = [];
    if (!adjacencyList[end]) adjacencyList[end] = [];

    adjacencyList[start].push({ end, weight });
  });

  minArr[start] = 0;
  pq.enqueue(start, 0);

  while (pq.values.length) {
    const { val, priority } = pq.dequeue();

    if (minArr[val] < priority) continue;
    minArr[val] = priority;

    adjacencyList[val]?.forEach((item) => {
      const { end, weight } = item;
      if (priority + weight < minArr[end]) {
        minArr[end] = priority + weight;
        pre[end] = val;
        pq.enqueue(end, minArr[end]);
      }
    });
  }

  function findPre(start, end) {
    answerRoute.push(end);
    if (start === end) return;

    return findPre(start, pre[end]);
  }

  findPre(start, end);

  return [
    minArr[end],
    answerRoute.length,
    answerRoute.reverse().join(' '),
  ].join('\n');
}

const depArr = input.splice(-1);
const answer = solution(
  Number(n),
  Number(m),
  input.map((item) => item.split(' ').map(Number)),
  depArr[0].split(' ').map(Number),
);

console.log(answer);

 

 

 

์šฐ์„ ์ˆœ์œ„ ํ ๊ตฌํ˜„ ์ฝ”๋“œ

class PriorityQueue {
  constructor() {
    this.values = [];
  }
  enqueue(val, priority) {
    let newNode = new Node(val, priority);
    this.values.push(newNode);
    this.bubbleUp();
  }
  bubbleUp() {
    let idx = this.values.length - 1;
    const element = this.values[idx];
    while (idx > 0) {
      let parentIdx = Math.floor((idx - 1) / 2);
      let parent = this.values[parentIdx];
      if (element.priority >= parent.priority) break;
      this.values[parentIdx] = element;
      this.values[idx] = parent;
      idx = parentIdx;
    }
  }
  dequeue() {
    const min = this.values[0];
    const end = this.values.pop();
    if (this.values.length > 0) {
      this.values[0] = end;
      this.sinkDown();
    }
    return min;
  }
  sinkDown() {
    let idx = 0;
    const length = this.values.length;
    const element = this.values[0];
    while (true) {
      let leftChildIdx = 2 * idx + 1;
      let rightChildIdx = 2 * idx + 2;
      let leftChild, rightChild;
      let swap = null;

      if (leftChildIdx < length) {
        leftChild = this.values[leftChildIdx];
        if (leftChild.priority < element.priority) {
          swap = leftChildIdx;
        }
      }
      if (rightChildIdx < length) {
        rightChild = this.values[rightChildIdx];
        if (
          (swap === null && rightChild.priority < element.priority) ||
          (swap !== null && rightChild.priority < leftChild.priority)
        ) {
          swap = rightChildIdx;
        }
      }
      if (swap === null) break;
      this.values[idx] = this.values[swap];
      this.values[swap] = element;
      idx = swap;
    }
  }
}

class Node {
  constructor(val, priority) {
    this.val = val;
    this.priority = priority;
  }
}