|
| 1 | +import Foundation |
| 2 | + |
| 3 | +@inline(__always) func readInt() -> Int { |
| 4 | + var c = getchar() |
| 5 | + var n = 0 |
| 6 | + while c == 10 || c == 32 { c = getchar() } |
| 7 | + var sign = 1 |
| 8 | + if c == 45 { sign = -1; c = getchar() } |
| 9 | + while c >= 48 { |
| 10 | + n = n &* 10 &+ Int(c - 48) |
| 11 | + c = getchar() |
| 12 | + } |
| 13 | + return n * sign |
| 14 | +} |
| 15 | + |
| 16 | +let N = readInt() |
| 17 | +let M = readInt() |
| 18 | + |
| 19 | +var graph = Array(repeating: [(to: Int, cost: Int)](), count: N + 1) |
| 20 | + |
| 21 | +var edges: [(u: Int, v: Int, w: Int)] = [] |
| 22 | +edges.reserveCapacity(M) |
| 23 | + |
| 24 | +for _ in 0..<M { |
| 25 | + let u = readInt() |
| 26 | + let v = readInt() |
| 27 | + let w = readInt() |
| 28 | + graph[u].append((v, w)) |
| 29 | + graph[v].append((u, w)) |
| 30 | + edges.append((u, v, w)) |
| 31 | +} |
| 32 | + |
| 33 | +struct PQ<T> { |
| 34 | + var heap: [T] = [] |
| 35 | + let cmp: (T, T) -> Bool |
| 36 | + |
| 37 | + mutating func push(_ x: T) { |
| 38 | + heap.append(x) |
| 39 | + var i = heap.count - 1 |
| 40 | + while i > 0 { |
| 41 | + let p = (i - 1) >> 1 |
| 42 | + if cmp(heap[i], heap[p]) { |
| 43 | + heap.swapAt(i, p) |
| 44 | + i = p |
| 45 | + } else { break } |
| 46 | + } |
| 47 | + } |
| 48 | + |
| 49 | + mutating func pop() -> T? { |
| 50 | + if heap.isEmpty { return nil } |
| 51 | + heap.swapAt(0, heap.count - 1) |
| 52 | + let ret = heap.removeLast() |
| 53 | + var i = 0 |
| 54 | + |
| 55 | + while true { |
| 56 | + let l = i * 2 + 1 |
| 57 | + let r = i * 2 + 2 |
| 58 | + var smallest = i |
| 59 | + if l < heap.count && cmp(heap[l], heap[smallest]) { smallest = l } |
| 60 | + if r < heap.count && cmp(heap[r], heap[smallest]) { smallest = r } |
| 61 | + if smallest == i { break } |
| 62 | + heap.swapAt(i, smallest) |
| 63 | + i = smallest |
| 64 | + } |
| 65 | + return ret |
| 66 | + } |
| 67 | + |
| 68 | + var isEmpty: Bool { heap.isEmpty } |
| 69 | +} |
| 70 | + |
| 71 | +let INF = Int.max |
| 72 | + |
| 73 | +func dijkstra(blockedEdge: (Int, Int)?) -> ([Int], [Int]) { |
| 74 | + var dist = Array(repeating: INF, count: N + 1) |
| 75 | + var prev = Array(repeating: -1, count: N + 1) |
| 76 | + |
| 77 | + var pq = PQ<(Int, Int)>(heap: [], cmp: { $0.1 < $1.1 }) |
| 78 | + dist[1] = 0 |
| 79 | + pq.push((1, 0)) |
| 80 | + |
| 81 | + while !pq.isEmpty { |
| 82 | + let (x, cost) = pq.pop()! |
| 83 | + if dist[x] < cost { continue } |
| 84 | + |
| 85 | + if x == N { break } |
| 86 | + |
| 87 | + for e in graph[x] { |
| 88 | + let y = e.to |
| 89 | + let w = e.cost |
| 90 | + |
| 91 | + // 차단 간선이면 skip |
| 92 | + if let block = blockedEdge { |
| 93 | + if (x == block.0 && y == block.1) || (x == block.1 && y == block.0) { |
| 94 | + continue |
| 95 | + } |
| 96 | + } |
| 97 | + |
| 98 | + let nc = cost + w |
| 99 | + if nc < dist[y] { |
| 100 | + dist[y] = nc |
| 101 | + prev[y] = x |
| 102 | + pq.push((y, nc)) |
| 103 | + } |
| 104 | + } |
| 105 | + } |
| 106 | + |
| 107 | + return (dist, prev) |
| 108 | +} |
| 109 | + |
| 110 | +let (dist0, prev0) = dijkstra(blockedEdge: nil) |
| 111 | +let base = dist0[N] |
| 112 | + |
| 113 | +if base == INF { |
| 114 | + print(-1) |
| 115 | + exit(0) |
| 116 | +} |
| 117 | + |
| 118 | +var pathEdges: [(Int, Int)] = [] |
| 119 | +var cur = N |
| 120 | +while prev0[cur] != -1 { |
| 121 | + pathEdges.append((prev0[cur], cur)) |
| 122 | + cur = prev0[cur] |
| 123 | +} |
| 124 | + |
| 125 | +var answer = 0 |
| 126 | +for (a, b) in pathEdges { |
| 127 | + let (distX, _) = dijkstra(blockedEdge: (a, b)) |
| 128 | + if distX[N] == INF { |
| 129 | + print(-1) |
| 130 | + exit(0) |
| 131 | + } |
| 132 | + let delay = distX[N] - base |
| 133 | + if delay > answer { answer = delay } |
| 134 | +} |
| 135 | + |
| 136 | +print(answer) |
0 commit comments