๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

Algorithm

[Algorithm] ์ตœ๋‹จ๊ฒฝ๋กœ (๋ฐฑ์ค€ - 1753)

๐Ÿ“‹ ๋ฌธ์ œ

๋ฐฉํ–ฅ๊ทธ๋ž˜ํ”„๊ฐ€ ์ฃผ์–ด์ง€๋ฉด ์ฃผ์–ด์ง„ ์‹œ์ž‘์ ์—์„œ ๋‹ค๋ฅธ ๋ชจ๋“  ์ •์ ์œผ๋กœ์˜ ์ตœ๋‹จ ๊ฒฝ๋กœ๋ฅผ ๊ตฌํ•˜๋Š” ํ”„๋กœ๊ทธ๋žจ์„ ์ž‘์„ฑํ•˜์‹œ์˜ค. ๋‹จ, ๋ชจ๋“  ๊ฐ„์„ ์˜ ๊ฐ€์ค‘์น˜๋Š” 10 ์ดํ•˜์˜ ์ž์—ฐ์ˆ˜์ด๋‹ค.

์ž…๋ ฅ

์ฒซ์งธ ์ค„์— ์ •์ ์˜ ๊ฐœ์ˆ˜ V์™€ ๊ฐ„์„ ์˜ ๊ฐœ์ˆ˜ E๊ฐ€ ์ฃผ์–ด์ง„๋‹ค. (1 ≤ V ≤ 20,000, 1 ≤ E ≤ 300,000) ๋ชจ๋“  ์ •์ ์—๋Š” 1๋ถ€ํ„ฐ V๊นŒ์ง€ ๋ฒˆํ˜ธ๊ฐ€ ๋งค๊ฒจ์ ธ ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•œ๋‹ค. ๋‘˜์งธ ์ค„์—๋Š” ์‹œ์ž‘ ์ •์ ์˜ ๋ฒˆํ˜ธ K(1 ≤ K ≤ V)๊ฐ€ ์ฃผ์–ด์ง„๋‹ค. ์…‹์งธ ์ค„๋ถ€ํ„ฐ E๊ฐœ์˜ ์ค„์— ๊ฑธ์ณ ๊ฐ ๊ฐ„์„ ์„ ๋‚˜ํƒ€๋‚ด๋Š” ์„ธ ๊ฐœ์˜ ์ •์ˆ˜ (u, v, w)๊ฐ€ ์ˆœ์„œ๋Œ€๋กœ ์ฃผ์–ด์ง„๋‹ค. ์ด๋Š” u์—์„œ v๋กœ ๊ฐ€๋Š” ๊ฐ€์ค‘์น˜ w์ธ ๊ฐ„์„ ์ด ์กด์žฌํ•œ๋‹ค๋Š” ๋œป์ด๋‹ค. u์™€ v๋Š” ์„œ๋กœ ๋‹ค๋ฅด๋ฉฐ w๋Š” 10 ์ดํ•˜์˜ ์ž์—ฐ์ˆ˜์ด๋‹ค. ์„œ๋กœ ๋‹ค๋ฅธ ๋‘ ์ •์  ์‚ฌ์ด์— ์—ฌ๋Ÿฌ ๊ฐœ์˜ ๊ฐ„์„ ์ด ์กด์žฌํ•  ์ˆ˜๋„ ์žˆ์Œ์— ์œ ์˜ํ•œ๋‹ค.

์ถœ๋ ฅ

์ฒซ์งธ ์ค„๋ถ€ํ„ฐ V๊ฐœ์˜ ์ค„์— ๊ฑธ์ณ, i๋ฒˆ์งธ ์ค„์— i๋ฒˆ ์ •์ ์œผ๋กœ์˜ ์ตœ๋‹จ ๊ฒฝ๋กœ์˜ ๊ฒฝ๋กœ๊ฐ’์„ ์ถœ๋ ฅํ•œ๋‹ค. ์‹œ์ž‘์  ์ž์‹ ์€ 0์œผ๋กœ ์ถœ๋ ฅํ•˜๊ณ , ๊ฒฝ๋กœ๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ์—๋Š” INF๋ฅผ ์ถœ๋ ฅํ•˜๋ฉด ๋œ๋‹ค.

์ž…์ถœ๋ ฅ ์˜ˆ

์˜ˆ์ œ ์ž…๋ ฅ ์˜ˆ์ œ ์ถœ๋ ฅ
5 6
1
5 1 1
1 2 2
1 3 3
2 3 4
2 4 5
3 4 6
0
2
3
7
INF

 

โœ๏ธ ํ’€์ด

๋‹ค์ต์ŠคํŠธ๋ผ๋ฅผ ์ด์šฉํ•ด์„œ ํ’€์—ˆ๋‹ค. ์ตœ๊ทผ ๋‹ค์ต์ŠคํŠธ๋ผ ๋ฌธ์ œ๋ฅผ ํ’€์—ˆ๋˜ ์ ์ด ์žˆ๋Š”๋ฐ ๊ทธ๋•Œ๋Š” ํž™์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•˜์—ˆ๋‹ค. ์ด๋ฒˆ์— ๋ฌธ์ œ๋ฅผ ํ’€๋ฉด์„œ console.log๋ฅผ ์ตœ์†Œํ™”ํ•˜๊ฑฐ๋‚˜, get, set์˜ ์ตœ์ ํ™”๋ฅผ ์œ„ํ•ด ์œ„์น˜์ •๋ณด๋ฅผ ์ €์žฅํ•˜๋Š” graph(์•„๋ž˜ ์ฝ”๋“œ ์ƒ dist)๋ฅผ ์ผ๋ฐ˜ ๊ฐ์ฒด๊ฐ€ ์•„๋‹Œ Map์„ ์ด์šฉํ•˜๊ฑฐ๋‚˜ ํ•ด๋„ ์‹œ๊ฐ„์ดˆ๊ณผ๊ฐ€ ๋ฐœ์ƒํ–ˆ๊ณ  ๊ฒฐ๊ตญ ํž™์„ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค.

 

๊ธฐ๋ณธ์ ์ธ ๋กœ์ง์€ ๋‹ค์ต์ŠคํŠธ๋ผ์™€ ๋™์ผํ•˜๋‹ค. ํ•˜๋‚˜์˜ ์ถœ๋ฐœ์ ์—์„œ ๋‹ค๋ฅธ ๋ชจ๋“  ๋…ธ๋“œ๊นŒ์ง€์˜ ๊ฑฐ๋ฆฌ๋ฅผ ๊ตฌํ•  ์ˆ˜ ์žˆ๋„๋ก ๋ฐฐ์—ด(visited)์„ ์‚ฌ์šฉํ•ด์„œ ํ˜„์žฌ ๋ฐฉ๋ฌธ ์ค‘์ธ ๋…ธ๋“œ์—์„œ ๋‹ค๋ฅธ ๋…ธ๋“œ๋กœ ์ด๋™ํ• ๋•Œ ์ตœ์†Œ์˜ ๋ฃจํŠธ๋ฅผ ๋ณ„๋„์˜ ๋ฐฐ์—ด(costs)์—์„œ ์ตœ์‹ ํ™”ํ•œ๋‹ค. ์œ ์ผํ•œ ์ฐจ์ด์ ์ด ๋‹ค์Œ์œผ๋กœ ๋ฐฉ๋ฌธํ•  ๋…ธ๋“œ๋ฅผ ์ •ํ•˜๋Š” ๋ถ€๋ถ„์ธ๋ฐ ํž™์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์„ ๋•Œ๋Š” ๋ชจ๋“  ๋…ธ๋“œ๋ฅผ ํƒ์ƒ‰ํ•˜๋ฉด์„œ ๋ฐฉ๋ฌธํ•˜์ง€ ์•Š๋Š” ๋…ธ๋“œ ์ค‘ ๊ฐ€์žฅ ์ตœ์†Œ์˜ ๋น„์šฉ์ด ๋“œ๋Š” ๋…ธ๋“œ๋กœ ๊ณจ๋ผ์„œ ์ด๋™ํ•˜์˜€๋‹ค. ํž™์„ ์‚ฌ์šฉํ–ˆ์„ ๋•Œ๋Š” ๊ฑฐ๋ฆฌ์ƒ์œผ๋กœ ์˜ค๋ฆ„์ฐจ์ˆœ์œผ๋กœ ์ •๋ ฌ๋˜๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ€์žฅ ์œ„ ๋…ธ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค. ์ด ๋ถ€๋ถ„์—์„œ ์‹œ๊ฐ„๋ณต์žก๋„ n์—์„œ LogN์œผ๋กœ ์ค„๋ฉฐ ์‹œ๊ฐ„์ดˆ๊ณผ ๋ฌธ์ œ๊ฐ€ ํ•ด๊ฒฐ๋œ ๊ฒƒ ๊ฐ™๋‹ค. 

 

โŒจ๏ธ ์ฝ”๋“œ

const fs = require('fs');
const filePath = process.platform === 'linux' ? '/dev/stdin' : './testcase/1753.txt';

let inputs = fs.readFileSync(filePath).toString().trim().split('\n');
inputs = inputs.map(str => str.split(' ').map(Number));

class MinHeap {
  constructor() {
    this.heap = [];
    this.heap.push(-1e9);
  }

  insert(value) {
    this.heap.push(value);
    this.upheap(this.heap.length - 1);
  }

  upheap(pos) {
    let temp = this.heap[pos];

    while (temp[1] < this.heap[parseInt(pos / 2)][1]) {
      this.heap[pos] = this.heap[parseInt(pos / 2)];
      pos = parseInt(pos / 2);
    }
    this.heap[pos] = temp;
  }

  get() {
    if (this.size() === 0) return 0;
    if (this.size() === 1) return this.heap.pop();
    const result = this.heap[1];
    this.heap[1] = this.heap.pop();
    this.downheap(1, this.heap.length - 1);
    return result;
  }

  downheap(pos, len) {
    let temp = this.heap[pos],
      child;
    while (pos <= parseInt(len / 2)) {
      child = pos * 2;
      if (child < len && this.heap[child][1] > this.heap[child + 1][1]) child++;
      if (temp[1] <= this.heap[child][1]) break;
      this.heap[pos] = this.heap[child];
      pos = child;
    }
    this.heap[pos] = temp;
  }

  size() {
    return this.heap.length - 1;
  }
}

const [V, E] = inputs[0];
const start = inputs[1][0];

const costs = new Array(V + 1).fill(Infinity);
const visited = new Array(V + 1).fill(0);

const dists = [...Array(V + 1)].map(_ => new Array());
for (let i = 2; i < inputs.length; i++) {
  const [u, v, w] = inputs[i];
  dists[u].push([v, w]);
}
costs[start] = 0;
const heap = new MinHeap();

heap.insert([start, 0]);

while (heap.size() > 0) {
  const [pos, dist] = heap.get();
  if (visited[pos]) continue;

  visited[pos] = true;
  for (let [next, dist] of dists[pos]) {
    if (costs[next] <= costs[pos] + dist) continue;
    costs[next] = dist + costs[pos];
    heap.insert([next, costs[next]]);
  }
}

const answer = [];
for (let i = 1; i <= V; i++) answer.push(costs[i] === Infinity ? 'INF' : costs[i]);
console.log(answer.join('\n'));