147 lines
4.5 KiB
Swift
147 lines
4.5 KiB
Swift
// 그냥 큐를 써도 통과가 되긴 하다만 연습삼아서 우선순위큐를 직접 구현해서 풀어봄
|
|
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..<M {
|
|
if let line = readLine(),
|
|
let info = line.split(separator: " ").compactMap({Int($0)}) as? [Int],
|
|
info.count == 3
|
|
{
|
|
let u = info[0]
|
|
let v = info[1]
|
|
let t = info[2]
|
|
|
|
graph[u].append((now: v, time: t))
|
|
reverse_graph[v].append((now: u, time: t))
|
|
}
|
|
}
|
|
|
|
var gotime = Array(repeating: Int.max, count: N+1) // N -> 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..<reverse_graph[current.now].count {
|
|
if comingtime[reverse_graph[current.now][i].now] > 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..<graph[current.now].count {
|
|
if gotime[graph[current.now][i].now] > 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)
|
|
}
|