1
1
#Uses python3
2
-
3
2
import sys
4
3
import queue
4
+ from collections import namedtuple
5
+
6
+ Edge = namedtuple ('Edge' , ['vertex' , 'weight' ])
7
+
8
+ class Graph :
9
+ def __init__ (self , n , edges ):
10
+ self .adjacency_list = [[] for _ in range (n )]
11
+ self .build_adjacency_list (edges )
12
+
13
+ def v_size (self ):
14
+ return len (self .adjacency_list )
15
+
16
+ def build_adjacency_list (self , edges ):
17
+ for ((s , d ), w ) in edges :
18
+ self .adjacency_list [s - 1 ].append (Edge (d - 1 , w ))
19
+
20
+ # Implementation: Bellman-Ford algorithm
21
+ def shortest_paths (self , s , distances ):
22
+ n = self .v_size ()
23
+ parents = [- 1 ] * n
24
+ distances [s ] = 0
25
+ negative_cycle_reachable_nodes = []
5
26
27
+ # Find shortest paths
28
+ for i in range (n ):
29
+ for v in range (n ):
30
+ for a_tuple in self .adjacency_list [v ]:
31
+ a_candidate_distance = distances [v ] + a_tuple .weight
32
+ if distances [a_tuple .vertex ] > a_candidate_distance :
33
+ distances [a_tuple .vertex ] = a_candidate_distance
34
+ parents [a_tuple .vertex ] = v
35
+
36
+ if i == n - 1 :
37
+ negative_cycle_reachable_nodes .append (a_tuple .vertex )
38
+ distances [s ] = - 10 ** 19
39
+
40
+ # Find all negative cycles
41
+ visited = [False ] * n
42
+ for v in negative_cycle_reachable_nodes :
43
+ cycle_v = self .get_cycle (v , parents )
44
+ # Visit all nodes reachable from a negative cycle
45
+ self .dfs (cycle_v , distances , visited )
46
+
47
+ def get_cycle (self , v , parents ):
48
+ # Find a node in a cycle where v is reachable from
49
+ cycle_v = v
50
+ for _ in range (self .v_size ()):
51
+ cycle_v = parents [cycle_v ]
6
52
7
- def shortet_paths (adj , cost , s , distance , reachable , shortest ):
8
- #write your code here
9
- pass
53
+ return cycle_v
10
54
55
+ # Find all nodes of the cycle
56
+ #cycle = []
57
+ #cycle.append(cycle_v)
58
+ #p = parents[cycle_v]
59
+ #while p != cycle_v:
60
+ # cycle.append(p)
61
+ # p = parents[p]
62
+ # return cycle
63
+
64
+ def dfs (self , s , distances , visited ):
65
+ if visited [s ]:
66
+ return
67
+
68
+ visited [s ] = True
69
+ distances [s ] = - 10 ** 19
70
+
71
+ for a_tuple in self .adjacency_list [s ]:
72
+ self .dfs (a_tuple .vertex , distances , visited )
73
+
74
+ def shortet_paths (n , edges , s , distance ):
75
+
76
+ aGraph = Graph (n , edges )
77
+
78
+ aGraph .shortest_paths (s , distances )
11
79
12
80
if __name__ == '__main__' :
13
81
input = sys .stdin .read ()
@@ -16,22 +84,15 @@ def shortet_paths(adj, cost, s, distance, reachable, shortest):
16
84
data = data [2 :]
17
85
edges = list (zip (zip (data [0 :(3 * m ):3 ], data [1 :(3 * m ):3 ]), data [2 :(3 * m ):3 ]))
18
86
data = data [3 * m :]
19
- adj = [[] for _ in range (n )]
20
- cost = [[] for _ in range (n )]
21
- for ((a , b ), w ) in edges :
22
- adj [a - 1 ].append (b - 1 )
23
- cost [a - 1 ].append (w )
87
+
24
88
s = data [0 ]
25
89
s -= 1
26
- distance = [10 ** 19 ] * n
27
- reachable = [0 ] * n
28
- shortest = [1 ] * n
29
- shortet_paths (adj , cost , s , distance , reachable , shortest )
90
+ distances = [10 ** 19 ] * n
91
+ shortet_paths (n , edges , s , distances )
30
92
for x in range (n ):
31
- if reachable [x ] == 0 :
93
+ if distances [x ] == 10 ** 19 :
32
94
print ('*' )
33
- elif shortest [x ] == 0 :
95
+ elif distances [x ] == - 10 ** 19 :
34
96
print ('-' )
35
97
else :
36
- print (distance [x ])
37
-
98
+ print (distances [x ])
0 commit comments