[μ€μννΈ μκ³ λ¦¬μ¦] νλ‘κ·Έλλ¨Έμ€: λ°°λ¬
λ¬Έμ
Nκ°μ λ§μλ‘ μ΄λ£¨μ΄μ§ λλΌκ° μμ΅λλ€. μ΄ λλΌμ κ° λ§μμλ 1λΆν° NκΉμ§μ λ²νΈκ° κ°κ° νλμ© λΆμ¬λμ΄ μμ΅λλ€. κ° λ§μμ μλ°©ν₯μΌλ‘ ν΅νν μ μλ λλ‘λ‘ μ°κ²°λμ΄ μλλ°, μλ‘ λ€λ₯Έ λ§μ κ°μ μ΄λν λλ μ΄ λλ‘λ₯Ό μ§λμΌ ν©λλ€. λλ‘λ₯Ό μ§λ λ 걸리λ μκ°μ λλ‘λ³λ‘ λ€λ¦ λλ€. νμ¬ 1λ² λ§μμ μλ μμμ μμ κ° λ§μλ‘ μμ λ°°λ¬μ νλ €κ³ ν©λλ€. κ° λ§μλ‘λΆν° μμ μ£Όλ¬Έμ λ°μΌλ €κ³ νλλ°, Nκ°μ λ§μ μ€μμ K μκ° μ΄νλ‘ λ°°λ¬μ΄ κ°λ₯ν λ§μμμλ§ μ£Όλ¬Έμ λ°μΌλ €κ³ ν©λλ€. λ€μμ N = 5, K = 3μΈ κ²½μ°μ μμμ λλ€.
μ κ·Έλ¦Όμμ 1λ² λ§μμ μλ μμμ μ [1, 2, 4, 5] λ² λ§μκΉμ§λ 3 μ΄νμ μκ°μ λ°°λ¬ν μ μμ΅λλ€. κ·Έλ¬λ 3λ² λ§μκΉμ§λ 3μκ° μ΄λ΄λ‘ λ°°λ¬ν μ μλ κ²½λ‘κ° μμΌλ―λ‘ 3λ² λ§μμμλ μ£Όλ¬Έμ λ°μ§ μμ΅λλ€. λ°λΌμ 1λ² λ§μμ μλ μμμ μ΄ λ°°λ¬ μ£Όλ¬Έμ λ°μ μ μλ λ§μμ 4κ°κ° λ©λλ€.
λ§μμ κ°μ N, κ° λ§μμ μ°κ²°νλ λλ‘μ μ 보 road, μμ λ°°λ¬μ΄ κ°λ₯ν μκ° Kκ° λ§€κ°λ³μλ‘ μ£Όμ΄μ§ λ, μμ μ£Όλ¬Έμ λ°μ μ μλ λ§μμ κ°μλ₯Ό return νλλ‘ solution ν¨μλ₯Ό μμ±ν΄μ£ΌμΈμ.
μ νμ¬ν
- λ§μμ κ°μ Nμ 1 μ΄μ 50 μ΄νμ μμ°μμ λλ€.
- roadμ κΈΈμ΄(λλ‘ μ 보μ κ°μ)λ 1 μ΄μ 2,000 μ΄νμ λλ€.
- roadμ κ° μμλ λ§μμ μ°κ²°νκ³ μλ κ° λλ‘μ μ 보λ₯Ό λνλ λλ€.
- roadλ κΈΈμ΄κ° 3μΈ λ°°μ΄μ΄λ©°, μμλλ‘ (a, b, c)λ₯Ό λνλ
λλ€.
- a, b(1 ≤ a, b ≤ N, a != b)λ λλ‘κ° μ°κ²°νλ λ λ§μμ λ²νΈμ΄λ©°, c(1 ≤ c ≤ 10,000, cλ μμ°μ)λ λλ‘λ₯Ό μ§λλλ° κ±Έλ¦¬λ μκ°μ λλ€.
- λ λ§μ a, bλ₯Ό μ°κ²°νλ λλ‘λ μ¬λ¬ κ°κ° μμ μ μμ΅λλ€.
- ν λλ‘μ μ λ³΄κ° μ¬λ¬ λ² μ€λ³΅ν΄μ μ£Όμ΄μ§μ§ μμ΅λλ€.
- Kλ μμ λ°°λ¬μ΄ κ°λ₯ν μκ°μ λνλ΄λ©°, 1 μ΄μ 500,000 μ΄νμ λλ€.
- μμμ λ λ§μκ°μ νμ μ΄λ κ°λ₯ν κ²½λ‘κ° μ‘΄μ¬ν©λλ€.
- 1λ² λ§μμ μλ μμμ μ΄ K μ΄νμ μκ°μ λ°°λ¬μ΄ κ°λ₯ν λ§μμ κ°μλ₯Ό return νλ©΄ λ©λλ€.
νμ΄
μ νμ μΈ λ€μ΅μ€νΈλΌ μκ³ λ¦¬μ¦μΌλ‘ μ΅λ¨κ±°λ¦¬λ₯Ό μ°Ύλ λ¬Έμ μμ΅λλ€. C++ κ³Όλ λ€λ₯΄κ² μ€μννΈμμλ νκ³Ό μ°μ μμν μλ£κ΅¬μ‘°κ° μμ΄μ μλ£κ΅¬μ‘°λ₯Ό μμ ν μλ‘ λ§λ€μ΄μ μ¬μ©νκ±°λ, λ°°μ΄μ μμλ€μ μ§μ΄λ£κ³ λΉΌλ΄κΈ° μ§μ μ μ°μ μμ κΈ°μ€μΌλ‘ μ λ ¬μ νκ³ μμλ₯Ό λΉΌλ λ°©λ²μΌλ‘ ν΄κ²°ν μ μμ΅λλ€. λ λ°©λ²μ λν μ½λλ₯Ό λͺ¨λ 첨λΆν©λλ€.
μ½λ
νκ³Ό μ°μ μμ νλ₯Ό μ μνμ§ μκ³ μ λ ¬μ ν΅ν΄ ν΄κ²°ν νμ΄
import Foundation
func calcDists(_ distances: inout [Int], _ costs: inout [[(Int, Int)]]) {
var pq : [(Int, Int)] = []
pq.append((1, 0))
distances[1] = 0
while(!pq.isEmpty) {
pq.sort(by: <)
let (here, costHere) = pq.removeFirst()
for (there, costThere) in costs[here] {
if distances[there] > costHere + costThere {
distances[there] = costHere + costThere
pq.append((there, distances[there]))
}
}
}
}
func solution(_ N:Int, _ road:[[Int]], _ k:Int) -> Int {
var distances = Array(repeating: 987654321, count: N + 1)
var costs = Array(repeating: [(Int, Int)](), count: N + 1)
for info in road {
costs[info[0]].append((info[1], info[2]))
costs[info[1]].append((info[0], info[2]))
}
calcDists(&distances, &costs)
return distances.filter({ $0 <= k }).count
}
νκ³Ό μ°μ μμ νλ₯Ό ꡬνν νμ΄
import Foundation
struct Heap<Element> {
var elements : [Element]
let sort : (Element, Element) -> Bool
var isEmpty : Bool {
return elements.isEmpty
}
var count : Int {
return elements.count
}
init(elements: [Element] = [], sort: @escaping (Element, Element) -> Bool) {
self.elements = elements
self.sort = sort
buildHeap()
}
// λ§μ§λ§ 리νλ
Έλμ λΆλͺ¨λ
ΈλλΆν° 루νΈλ
ΈλκΉμ§ diveDownμ μννλ€.
mutating func buildHeap() {
for index in (0..<(count / 2)).reversed() {
diveDown(from: index)
}
}
func peek() -> Element? {
return elements.first
}
func isRoot(_ index: Int) -> Bool {
return index == 0
}
func leftChildIndex(of index: Int) -> Int {
return (2 * index) + 1
}
func rightChildIndex(of index: Int) -> Int {
return (2 * index) + 2
}
func parentIndex(of index: Int) -> Int {
return (index - 1) / 2
}
func isWithHigherPriority (at firstIdx: Int, than secondIdx: Int) -> Bool {
return sort(elements[firstIdx], elements[secondIdx])
}
// μΌμͺ½ μλ
λ
Έλκ° μλ κ²½μ°μλ λΆλͺ¨λ
Έλμ λΉκ΅νμ¬ λ ν° λ
Έλμ μΈλ³μ€λ₯Ό λ°ννκ³ , μλ€λ©΄ λΆλͺ¨λ
Έλμ μΈλ±μ€λ₯΄ λ°ννλ€.
func higherPriorityWithChild(parentIndex: Int, childIndex: Int) -> Int {
guard childIndex < count && isWithHigherPriority(at: childIndex, than: parentIndex) else {
return parentIndex
}
return childIndex
}
// μΌμͺ½ μλ
λ
Έλμ λΆλͺ¨λ
Έλ μ€ μ°μ μμκ° λ ν° λ
Έλμ μ€λ₯Έμͺ½ μλ
λ
Έλλ₯Ό λΉκ΅νμ¬ λ ν° λ
Έλμ μΈλ±μ€λ₯Ό λ°ννλ€.
func higherPriorityOfChildren(for parent: Int) -> Int {
return higherPriorityWithChild(
parentIndex: higherPriorityWithChild(parentIndex: parent,
childIndex: leftChildIndex(of: parent)),
childIndex: rightChildIndex(of: parent))
}
mutating func swapElement (at firstIndex: Int, with secondIndex: Int){
elements.swapAt(firstIndex, secondIndex)
}
// νΈλ¦¬μ κ°μ₯ λ§μ§λ§μ μλ‘μ΄ λ
Έλλ₯Ό μ½μ
νκ³ swimUpμΌλ‘ νΈλ¦¬λ₯Ό μ¬μ‘°μ νλ€.
mutating func push (_ element: Element) {
elements.append(element)
swimUp(fromIndex: count - 1)
}
// μ§μ λ μΈλ±μ€λΆν° μμ μ λΆλͺ¨λ
Έλμ λΉκ΅νλ©΄μ λΆλͺ¨λ
Έλλ³΄λ€ μ°μ μμκ° λλ€λ©΄ λ λ
Έλλ₯Ό κ΅μ²΄ν λ€ μλ‘κ² λΆλͺ¨λ
Έλκ° λ λ
ΈλλΆν° swimUpμ λ€μ μννλ€.
mutating func swimUp(fromIndex index: Int) {
let parentIdx = parentIndex(of: index)
guard !isRoot(index), isWithHigherPriority(at: index, than: parentIdx) else {
return
}
swapElement(at: index, with: parentIdx)
swimUp(fromIndex: parentIdx)
}
// 루νΈλ
Έλμ λ΄μ©μ λ§μ§λ§ 리νλ
Έλμ λ΄μ©κ³Ό κ΅ννλ€ λ§μ§λ§ 리νλ
Έλλ₯Ό λΌμ΄λ²λ¦°λ€. κ·Έλ¦¬κ³ λ£¨νΈλ
ΈλλΆν° diveDownμ μννμ¬ νΈλ¦¬λ₯Ό μ¬μ‘°μ νλ€.
mutating func pop() -> Element? {
guard !isEmpty else {
return nil
}
swapElement(at: 0, with: count - 1)
let removedElement = elements.removeLast()
if !isEmpty {
diveDown(from: 0)
}
return removedElement
}
// λΆλͺ¨λ
Έλμ μλ
λ
Έλλ₯Ό λΉκ΅νλ©΄μ μλ
λ
Έλμ μ°μ μμκ° λ λλ€λ©΄ κ΅ννλ€.
mutating func diveDown(from index: Int){
let childIndex = higherPriorityOfChildren(for: index)
if index == childIndex {
return
}
swapElement(at: index, with: childIndex)
diveDown(from: childIndex)
}
}
struct PriorityQueue<T> {
var heap: Heap<T>
init(_ elements: [T], _ sort: @escaping (T, T) -> Bool) {
heap = Heap(elements: elements, sort: sort)
}
var count : Int {
return heap.count
}
var isEmpty : Bool {
return heap.isEmpty
}
mutating func clear () {
heap = Heap<T>(elements: [], sort: heap.sort)
}
func top () -> T? {
return heap.peek()
}
mutating func pop() -> T? {
return heap.pop()
}
mutating func push(_ element: T) {
heap.push(element)
}
}
func calcDists(_ distances: inout [Int], _ costs: inout [[(Int, Int)]]) {
var pq = PriorityQueue<(Int, Int)>([], { $0.1 < $1.1 })
pq.push((1, 0))
distances[1] = 0
while(!pq.isEmpty) {
let (here, costHere) = pq.pop()!
for (there, costThere) in costs[here] {
if distances[there] > costHere + costThere {
distances[there] = costHere + costThere
pq.push((there, distances[there]))
}
}
}
}
func solution(_ N:Int, _ road:[[Int]], _ k:Int) -> Int {
var distances = Array(repeating: 987654321, count: N + 1)
var costs = Array(repeating: [(Int, Int)](), count: N + 1)
for info in road {
costs[info[0]].append((info[1], info[2]))
costs[info[1]].append((info[0], info[2]))
}
calcDists(&distances, &costs)
return distances.filter({ $0 <= k }).count
}