// TRITIUM-PROVENANCE sha256=cecf307e190155d45c2cc7a93a750de16f8670bcbb0f247d9967748079f4e335 lang=rust // TRITIUM-HEIGHT high=1.00 mid=0.00 low=0.00 fn dist_init(dist: &mut [i64], n: i64, start: i64, inf: i64) -> i64 { let mut i = 0; while i < n { dist[i as usize] = inf; i += 1; } dist[start as usize] = 0; 0 } fn heap_push(heap_dist: &mut [i64], heap_node: &mut [i64], n: i64, d: i64, u: i64) -> i64 { let mut parent = 0; let mut i = n; heap_dist[i as usize] = d; heap_node[i as usize] = u; while i > 0 { parent = (i - 1) / 2; if heap_dist[i as usize] >= heap_dist[parent as usize] { break; } let mut swap = heap_dist[i as usize]; heap_dist[i as usize] = heap_dist[parent as usize]; heap_dist[parent as usize] = swap; let mut tmp_node = heap_node[i as usize]; heap_node[i as usize] = heap_node[parent as usize]; heap_node[parent as usize] = tmp_node; i = parent; } n + 1 } fn heap_min_d(heap_dist: &[i64], heap_node: &[i64], n: i64) -> i64 { heap_dist[0] } fn heap_min_u(heap_dist: &[i64], heap_node: &[i64], n: i64) -> i64 { heap_node[0] } fn heap_pop(heap_dist: &mut [i64], heap_node: &mut [i64], n: i64) -> i64 { let mut left = 0; let mut right = 0; let mut best = 0; let mut diff = n - 1; heap_dist[0] = heap_dist[diff as usize]; heap_node[0] = heap_node[diff as usize]; let mut i = 0; diff -= 1; loop { left = (i * 2) + 1; right = left + 1; if left > diff { break; } best = left; if right <= diff { if heap_dist[right as usize] < heap_dist[left as usize] { best = right; } } if heap_dist[i as usize] <= heap_dist[best as usize] { break; } let mut swap = heap_dist[i as usize]; heap_dist[i as usize] = heap_dist[best as usize]; heap_dist[best as usize] = swap; let mut tmp_node = heap_node[i as usize]; heap_node[i as usize] = heap_node[best as usize]; heap_node[best as usize] = tmp_node; i = best; } n - 1 } fn list_get(a: &[i64], i: i64) -> i64 { if i < 0 { return 0; } let i = i as usize; if i >= a.len() { 0 } else { a[i] } } fn stale_visit(dist: &[i64], u: i64, d: i64) -> i64 { if d > list_get(dist, u) { 1 } else { 0 } } fn relax_edge(dist: &mut [i64], heap_dist: &mut [i64], heap_node: &mut [i64], heap_len: i64, u: i64, v: i64, w: i64) -> i64 { let mut heap_len_2 = heap_len; let mut sum = dist[u as usize] + w; if sum < dist[v as usize] { dist[v as usize] = sum; heap_len_2 = heap_push(heap_dist, heap_node, heap_len_2, sum, v); } heap_len_2 } fn edge_relax(dist: &mut [i64], heap_dist: &mut [i64], heap_node: &mut [i64], heap_len: i64, dest: &[i64], weight: &[i64], e: i64, u: i64) -> i64 { relax_edge(dist, heap_dist, heap_node, heap_len, u, list_get(dest, e), list_get(weight, e)) } fn scan_neighbors(dist: &mut [i64], heap_dist: &mut [i64], heap_node: &mut [i64], heap_len: i64, dest: &[i64], weight: &[i64], offsets: &[i64], u: i64) -> i64 { let mut heap_len_2 = heap_len; let mut idx = list_get(offsets, u); while idx < list_get(offsets, u + 1) { heap_len_2 = edge_relax(dist, heap_dist, heap_node, heap_len_2, dest, weight, idx, u); idx += 1; } heap_len_2 } fn dijkstra(n: i64, offsets: &[i64], dest: &[i64], weight: &[i64], start: i64, dist: &mut [i64], heap_dist: &mut [i64], heap_node: &mut [i64]) -> i64 { let mut u = 0; let mut inf = 1000000000; dist_init(dist, n, start, inf); let mut heap_len = heap_push(heap_dist, heap_node, 0, 0, start); while heap_len > 0 { u = heap_min_u(heap_dist, heap_node, heap_len); heap_len = heap_pop(heap_dist, heap_node, heap_len); if stale_visit(dist, u, heap_min_d(heap_dist, heap_node, heap_len)) != 1 { heap_len = scan_neighbors(dist, heap_dist, heap_node, heap_len, dest, weight, offsets, u); } } 0 }