// 그냥 큐를 써도 통과가 되긴 하다만 연습삼아서 우선순위큐를 직접 구현해서 풀어봄 struct PriorityQueue { private var heap: [(now: Int, time: Int)] = [] public var isEmpty: Bool { return heap.isEmpty } public var count: Int { return heap.count } public func peek() -> (now: Int, time: Int)? { return heap.first } public mutating func enqueue(_ element: (now: Int, time: Int)) { heap.append(element) siftUp(from: heap.count - 1) } public mutating func dequeue() -> (now: Int, time: Int)? { guard !heap.isEmpty else { return nil } if heap.count == 1 { return heap.removeLast() } heap.swapAt(0, heap.count - 1) let dequeuedElement = heap.removeLast() siftDown(from: 0) return dequeuedElement } private func parentIndex(of i: Int) -> Int { (i - 1) / 2 } private func leftChildIndex(of i: Int) -> Int { 2 * i + 1 } private func rightChildIndex(of i: Int) -> Int { 2 * i + 2 } private mutating func siftUp(from index: Int) { var childIndex = index var parentIndex = self.parentIndex(of: childIndex) while childIndex > 0 && heap[childIndex].time < heap[parentIndex].time { heap.swapAt(childIndex, parentIndex) childIndex = parentIndex parentIndex = self.parentIndex(of: childIndex) } } private mutating func siftDown(from index: Int) { var parentIndex = index while true { let leftIndex = leftChildIndex(of: parentIndex) let rightIndex = rightChildIndex(of: parentIndex) var smallestIndex = parentIndex if leftIndex < heap.count && heap[leftIndex].time < heap[smallestIndex].time { smallestIndex = leftIndex } if rightIndex < heap.count && heap[rightIndex].time < heap[smallestIndex].time { smallestIndex = rightIndex } if smallestIndex == parentIndex { return } heap.swapAt(parentIndex, smallestIndex) parentIndex = smallestIndex } } } if let input = readLine(), let nums = input.split(separator: " ").compactMap({Int($0)}) as? [Int], nums.count == 3 { let N = nums[0] let M = nums[1] let X = nums[2] var graph: [[(now: Int, time: Int)]] = Array(repeating: [], count: N+1) var reverse_graph: [[(now: Int, time: Int)]] = Array(repeating: [], count: N+1) for _ in 0.. X var comingtime = Array(repeating: Int.max, count: N+1) // X -> N var pq = PriorityQueue() pq.enqueue((now: X, time: 0)) comingtime[X] = 0 while !pq.isEmpty { if let current = pq.dequeue() { if comingtime[current.now] < current.time { continue } for i in 0.. current.time + reverse_graph[current.now][i].time { comingtime[reverse_graph[current.now][i].now] = current.time + reverse_graph[current.now][i].time pq.enqueue((now: reverse_graph[current.now][i].now, time: current.time + reverse_graph[current.now][i].time)) } } } } pq.enqueue((now: X, time: 0)) gotime[X] = 0 while !pq.isEmpty { if let current = pq.dequeue() { if gotime[current.now] < current.time { continue } for i in 0.. current.time + graph[current.now][i].time { gotime[graph[current.now][i].now] = current.time + graph[current.now][i].time pq.enqueue((now: graph[current.now][i].now, time: current.time + graph[current.now][i].time)) } } } } var maxTime = 0; for n in 1...N { maxTime = max(maxTime, comingtime[n] + gotime[n]) } print(maxTime) }