1- use std:: collections:: BTreeMap ;
1+ use std:: collections:: { BTreeMap , BTreeSet } ;
22use std:: ops:: Add ;
33
44type Graph < V , E > = BTreeMap < V , BTreeMap < V , E > > ;
55
66// performs Dijsktra's algorithm on the given graph from the given start
7- // the graph is a positively-weighted undirected graph
7+ // the graph is a positively-weighted directed graph
88//
99// returns a map that for each reachable vertex associates the distance and the predecessor
1010// since the start has no predecessor but is reachable, map[start] will be None
@@ -17,17 +17,17 @@ pub fn dijkstra<V: Ord + Copy, E: Ord + Copy + Add<Output = E>>(
1717 start : V ,
1818) -> BTreeMap < V , Option < ( V , E ) > > {
1919 let mut ans = BTreeMap :: new ( ) ;
20- let mut prio = BTreeMap :: new ( ) ;
20+ let mut prio = BTreeSet :: new ( ) ;
2121
2222 // start is the special case that doesn't have a predecessor
2323 ans. insert ( start, None ) ;
2424
2525 for ( new, weight) in & graph[ & start] {
2626 ans. insert ( * new, Some ( ( start, * weight) ) ) ;
27- prio. insert ( * new , * weight ) ;
27+ prio. insert ( ( * weight , * new ) ) ;
2828 }
2929
30- while let Some ( ( vertex , path_weight ) ) = prio. pop_first ( ) {
30+ while let Some ( ( path_weight , vertex ) ) = prio. pop_first ( ) {
3131 for ( next, weight) in & graph[ & vertex] {
3232 let new_weight = path_weight + * weight;
3333 match ans. get ( next) {
@@ -37,8 +37,12 @@ pub fn dijkstra<V: Ord + Copy, E: Ord + Copy + Add<Output = E>>(
3737 Some ( None ) => { }
3838 // the new path is shorter, either new was not in ans or it was farther
3939 _ => {
40- ans. insert ( * next, Some ( ( vertex, new_weight) ) ) ;
41- prio. insert ( * next, new_weight) ;
40+ if let Some ( Some ( ( _, prev_weight) ) ) =
41+ ans. insert ( * next, Some ( ( vertex, new_weight) ) )
42+ {
43+ prio. remove ( & ( prev_weight, * next) ) ;
44+ }
45+ prio. insert ( ( new_weight, * next) ) ;
4246 }
4347 }
4448 }
0 commit comments