|
| 1 | +import sys |
| 2 | +import queue |
| 3 | +from collections import namedtuple |
| 4 | + |
| 5 | +Edge = namedtuple('Edge', ['vertex', 'weight']) |
| 6 | + |
| 7 | +class Graph: |
| 8 | + def __init__(self, n, edges): |
| 9 | + self.adjacency_list = [[] for _ in range(n)] |
| 10 | + self.build_adjacency_list(n, edges) |
| 11 | + |
| 12 | + def build_adjacency_list(self, n, edges): |
| 13 | + for ((s, d), w) in edges: |
| 14 | + self.adjacency_list[s - 1].append(Edge(d - 1, w)) |
| 15 | + |
| 16 | + # Implementation: Binary Heap |
| 17 | + # ... The number of flight ~ the number of cities => |V| ~ |E| => Sparse Graph => Binary Heap is more efficient |
| 18 | + # ... T(n) = O((|V| + |E|) log |V|) |
| 19 | + def dijkstra(self, s, t): |
| 20 | + |
| 21 | + # w <= 10^3 and |V| <= 10^4 |
| 22 | + # Shortest Path Cost <= 10^3 * 10^4 + 1 |
| 23 | + distances = [10**7 + 1] * len(self.adjacency_list) |
| 24 | + distances[s] = 0 |
| 25 | + |
| 26 | + parents = [None] * len(self.adjacency_list) |
| 27 | + parents[s] = -1 |
| 28 | + |
| 29 | + q = queue.PriorityQueue() |
| 30 | + for v in range(0, len(self.adjacency_list)): |
| 31 | + if v == s: |
| 32 | + continue |
| 33 | + q.put([distances[v], v]) |
| 34 | + q.put([distances[s], s]) |
| 35 | + |
| 36 | + while not q.empty(): |
| 37 | + v_min_weight = q.get() |
| 38 | + v = v_min_weight[1] |
| 39 | + |
| 40 | + if v == t: |
| 41 | + return distances[t] |
| 42 | + |
| 43 | + for a_tuple in self.adjacency_list[v]: |
| 44 | + a_candidate_distance = distances[v] + a_tuple.weight |
| 45 | + if distances[a_tuple.vertex] > a_candidate_distance: |
| 46 | + distances[a_tuple.vertex] = a_candidate_distance |
| 47 | + parents[a_tuple.vertex] = v |
| 48 | + q.put([distances[a_tuple.vertex], a_tuple.vertex]) |
| 49 | + |
| 50 | + return distances[t] |
| 51 | + |
| 52 | +def distance(n, edges, s, t): |
| 53 | + |
| 54 | + aFlightNetwork = Graph(n, edges) |
| 55 | + distance = aFlightNetwork.dijkstra(s, t) |
| 56 | + return -1 if distance == 10**7 + 1 else distance |
| 57 | + |
| 58 | +if __name__ == '__main__': |
| 59 | + input = sys.stdin.read() |
| 60 | + data = list(map(int, input.split())) |
| 61 | + n, m = data[0:2] |
| 62 | + data = data[2:] |
| 63 | + edges = list(zip(zip(data[0:(3 * m):3], data[1:(3 * m):3]), data[2:(3 * m):3])) |
| 64 | + data = data[3 * m:] |
| 65 | + s, t = data[0] - 1, data[1] - 1 |
| 66 | + print(distance(n, edges, s, t)) |
0 commit comments