|
| 1 | +/* |
| 2 | +โญ๏ธ ๋ฌธ์ ์ ๋ณด โญ๏ธ |
| 3 | +๋ฌธ์ : 72413 - ํฉ์น ํ์ ์๊ธ |
| 4 | +๋ ๋ฒจ : Level 3 |
| 5 | +๋งํฌ : https://school.programmers.co.kr/learn/courses/30/lessons/72413 |
| 6 | +*/ |
| 7 | + |
| 8 | +// ANCHOR: 26.02.08 ํ์ด |
| 9 | +class Heap { |
| 10 | + constructor(compare) { |
| 11 | + this.heap = []; |
| 12 | + this.compare = compare; |
| 13 | + } |
| 14 | + |
| 15 | + size() { |
| 16 | + return this.heap.length; |
| 17 | + } |
| 18 | + |
| 19 | + // ์๋ก์ด ์์๋ฅผ ํ์ ์ถ๊ฐ |
| 20 | + // ๊ฐ์ฅ ๋์ ๋ฃ๊ณ ์ ์๋ฆฌ๋ฅผ ์ฐพ์์ ์ฌ๋ ค์ค๋ค. |
| 21 | + push(value) { |
| 22 | + this.heap.push(value); |
| 23 | + this.siftUp(this.heap.length - 1); |
| 24 | + } |
| 25 | + |
| 26 | + // root๋ฅผ ๋บ๋ค. |
| 27 | + // ๊ฐ์ฅ ๋ ๊ฐ์ root๋ก ์ฌ๋ฆฌ๊ณ , ์ ์๋ฆฌ๋ฅผ ์ฐพ์ ๋ด๋ฆฐ๋ค. |
| 28 | + pop() { |
| 29 | + if (this.size() <= 0) return null; // NOTE : ๋ช
์์ ์ผ๋ก ๊ฐ์ ๋ฐํํด์ฃผ๋ ์ชฝ์ด ๋ ์ข์ |
| 30 | + if (this.size() === 1) return this.heap.pop(); // NOTE : ์ด๊ฑฐ ์์ง ๋ง์๋ค. |
| 31 | + const ret = this.heap[0]; |
| 32 | + this.heap[0] = this.heap.pop(); |
| 33 | + this.siftDown(0); |
| 34 | + return ret; |
| 35 | + } |
| 36 | + |
| 37 | + // ์ธ๋ฑ์ค ๊ณต์... (์๊ธฐ๊ฐ ํ์ํจ...) |
| 38 | + // parent: ์์ ๋์ด ๊ฐ์ ๋ถ๋ชจ๋ฅผ ๊ณต์ ํ๋ค. (1, 2) -> 3, => Math.floor((i - 1) / 2) |
| 39 | + // child: left child ๋ถํฐ ์๊ฐํ๊ธฐ. ๋ถ๋ชจ ํ๋๋น ์์ 2์นธ์ด ์๊ธด๋ค. |
| 40 | + // - left: 0 -> 1, 1 -> 3, ... => (i * 2) + 1 |
| 41 | + // - right: left ์. => (i * 2) + 2 |
| 42 | + |
| 43 | + // push์ ํจ๊ป ์ฌ์ฉ |
| 44 | + // ์ ์๋ฆฌ ์ฐพ์์ ์ฌ๋ผ๊ฐ๋ ๋จ๊ณ |
| 45 | + siftUp(idx) { |
| 46 | + // heap ๊ท์น์ ์ด๊ธ๋๋ค๋ฉด swap์ผ๋ก ์ฌ๋ ค์ค๋ค. |
| 47 | + // root์ด๊ฑฐ๋ heap ๊ท์น์ ์ ๋ง๋๋ค๋ฉด shiftUp ์ค๋จ |
| 48 | + while (idx > 0) { |
| 49 | + const parent = Math.floor((idx - 1) / 2); |
| 50 | + if (this.compare(this.heap[idx], this.heap[parent])) { |
| 51 | + this.swap(idx, parent); |
| 52 | + idx = parent; |
| 53 | + } else { |
| 54 | + break; |
| 55 | + } |
| 56 | + } |
| 57 | + } |
| 58 | + |
| 59 | + // pop๊ณผ ํจ๊ป ์ฌ์ฉ |
| 60 | + // ์ ์๋ฆฌ ์ฐพ์์ ๋ด๋ ค๊ฐ๋ ๋จ๊ณ |
| 61 | + siftDown(idx) { |
| 62 | + while (true) { |
| 63 | + const leftChild = idx * 2 + 1; |
| 64 | + const rightChild = idx * 2 + 2; |
| 65 | + |
| 66 | + let targetChild; |
| 67 | + if (leftChild >= this.size()) break; |
| 68 | + else if (rightChild >= this.size()) targetChild = leftChild; |
| 69 | + else |
| 70 | + targetChild = this.compare(this.heap[leftChild], this.heap[rightChild]) |
| 71 | + ? leftChild |
| 72 | + : rightChild; |
| 73 | + |
| 74 | + if (this.compare(this.heap[targetChild], this.heap[idx])) { |
| 75 | + this.swap(targetChild, idx); |
| 76 | + idx = targetChild; |
| 77 | + } else { |
| 78 | + break; |
| 79 | + } |
| 80 | + } |
| 81 | + } |
| 82 | + |
| 83 | + // a ์ธ๋ฑ์ค์ b์ธ๋ฑ์ค์ ๊ฐ์ ์ค์ |
| 84 | + swap(a, b) { |
| 85 | + [this.heap[a], this.heap[b]] = [this.heap[b], this.heap[a]]; |
| 86 | + } |
| 87 | +} |
| 88 | + |
| 89 | +function solution(n, s, a, b, fares) { |
| 90 | + // 0. ๋ค์ต์คํธ๋ผ์ ํ์ํ ๋ฐ์ดํฐ ์ค๋นํ๊ธฐ |
| 91 | + // adj: ์ธ์ ๋ฆฌ์คํธ (์์: [v, w]) |
| 92 | + const adj = Array.from({ length: n + 1 }, () => []); |
| 93 | + for (const [c, d, f] of fares) { |
| 94 | + adj[c].push([d, f]); |
| 95 | + adj[d].push([c, f]); |
| 96 | + } |
| 97 | + |
| 98 | + // 1. ๋ค์ต์คํธ๋ผ ๊ตฌํ |
| 99 | + // start: ๊ฒฝ๋ก๋ฅผ ๊ณ์ฐํ ์์ ์ง์ . |
| 100 | + // ์์ ์ง์ ๋ถํฐ ๋ค๋ฅธ ์ ์ฒด ๋
ธ๋๊น์ง์ ๊ฐ ์ต๋จ ๊ฒฝ๋ก๋ฅผ ๋ฐํํ๋ค. |
| 101 | + function dijkstra(start) { |
| 102 | + // 0) ์ด๊ธฐ ์ค์ |
| 103 | + const dist = new Array(n + 1).fill(Infinity); |
| 104 | + dist[start] = 0; |
| 105 | + const minHeap = new Heap(([c1, v1], [c2, v2]) => c1 < c2); |
| 106 | + minHeap.push([0, start]); |
| 107 | + |
| 108 | + // 1) minHeap์ด ๋น ๋๊น์ง ๋ฐ๋ณตํ๋ค. |
| 109 | + while (minHeap.size() > 0) { |
| 110 | + const [cost, u] = minHeap.pop(); |
| 111 | + // NOTE : dist ์ ๋ณด์ cost ์ ๋ณด๊ฐ ๋ค๋ฅด๋ค๋ฉด ๊ตฌ๋ฒ์ ์ ๋ณด์ด๋ฏ๋ก ๋์ด๊ฐ๋ค. (์ด๋ฏธ ์ฒ๋ฆฌํ ๋
ธ๋์์ ์๋ฏธ) |
| 112 | + if (cost !== dist[u]) continue; |
| 113 | + // 2) u์ ๊ฐ์ ๋ค์ ๋ชจ๋ ํ์ํ๋ค. |
| 114 | + for (const [v, w] of adj[u]) { |
| 115 | + // 3) v๋ก ๊ฐ๋๋ฐ ๊ฑธ๋ฆฌ๋ ๋น์ฉ์ ์ต์๊ฐ์ ์
๋ฐ์ดํธํ๋ค. |
| 116 | + const nextCost = cost + w; |
| 117 | + if (nextCost < dist[v]) { |
| 118 | + dist[v] = nextCost; |
| 119 | + minHeap.push([nextCost, v]); |
| 120 | + } |
| 121 | + } |
| 122 | + } |
| 123 | + |
| 124 | + return dist; |
| 125 | + } |
| 126 | + |
| 127 | + // 2. S์์ ์ถ๋ฐํ๋ ๊ฒฝ๋ก์ ์ดค๋จ๊ฑฐ๋ฆฌ |
| 128 | + const distS = dijkstra(s); |
| 129 | + // 3. A์์ ์ถ๋ฐํ๋ ๊ฒฝ๋ก์ ์ต๋จ๊ฑฐ๋ฆฌ (์ค๊ฐ์ง์ - A๊น์ง์ ๊ฑฐ๋ฆฌ ๊ณ์ฐ์ฉ) |
| 130 | + const distA = dijkstra(a); |
| 131 | + // 4. B์์ ์ถ๋ฐํ๋ ๊ฒฝ๋ก์ ์ต๋จ๊ฑฐ๋ฆฌ (์ค๊ฐ์ง์ - B๊น์ง์ ๊ฑฐ๋ฆฌ ๊ณ์ฐ์ฉ) |
| 132 | + const distB = dijkstra(b); |
| 133 | + |
| 134 | + // 5. ๋ชจ๋ ์ค๊ฐ์ง์ c๋ฅผ ํ์ธํ๋ฉด์ ์ด ๋น์ฉ์ด ์ต์๊ฐ ๋๋ c๋ฅผ ์ฐพ๋๋ค. |
| 135 | + // ํฉ์น์ ์ํด๋ ๋๊ธฐ ๋๋ฌธ์ ์์์ง์ ๋ ํ์ธํ๋ค. |
| 136 | + let answer = Infinity; |
| 137 | + for (let c = 1; c <= n; c++) { |
| 138 | + answer = Math.min(answer, distS[c] + distA[c] + distB[c]); |
| 139 | + } |
| 140 | + return answer; |
| 141 | +} |
0 commit comments