2025-10-14 19:27:27 +09:00

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)
}