Problem:
MathJax.Hub.Config({ tex2jax: { inlineMath: [["$","$"], ["\\(","\\)"]], processEscapes: true }});

Single Source Shortest Path II

For a given weighted graph $G = (V, E)$, find the shortest path from a source to each vertex. For each vertex $u$, print the total weight of edges on the shortest path from vertex $0$ to $u$.

Input

In the first line, an integer $n$ denoting the number of vertices in $G$ is given. In the following $n$ lines, adjacency lists for each vertex $u$ are respectively given in the following format:

$u$ $k$ $v_1$ $c_1$ $v_2$ $c_2$ ... $v_k$ $c_k$

Vertices in $G$ are named with IDs $0, 1, ..., n-1$. $u$ is ID of the target vertex and $k$ denotes its degree. $v_i (i = 1, 2, ... k)$ denote IDs of vertices adjacent to $u$ and $c_i$ denotes the weight of a directed edge connecting $u$ and $v_i$ (from $u$ to $v_i$).

Output

For each vertex, print its ID and the distance separated by a space character in a line respectively. Print in order of vertex IDs.

Constraints

$1 \leq n \leq 10,000$

$0 \leq c_i \leq 100,000$

$|E| < 500,000$

All vertices are reachable from vertex $0$

Sample Input 1

5
0 3 2 3 3 1 1 2
1 2 0 2 3 4
2 3 0 3 3 1 4 1
3 4 2 1 0 1 1 4 4 3
4 2 2 1 3 3

Sample Output 1

0 0
1 2
2 2
3 1
4 3

Reference

Introduction to Algorithms, Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein. The MIT Press.

Solution in OCaml (judge verdict: Accepted)

module MakeBinaryHeap (M : sig type t val compare : t -> t -> int end) = struct
  type t = { node : M.t array; mutable size : int }

  let make n (init : M.t) = { node = Array.make n init; size = 0 }

  let empty_p t = if t.size = 0 then true else false

  let pop t =
    let ret = t.node.(1) in
    t.node.(1) <- t.node.(t.size);
    t.size <- t.size - 1;
    let rec max_heapify i =
      let l = 2*i in
      let r = 2*i + 1 in
      let m = if l <= t.size && M.compare t.node.(l) t.node.(i) > 0 then l else i in
      let m = if r <= t.size && M.compare t.node.(r) t.node.(m) > 0 then r else m in
      if m <> i then begin
        let tmp = t.node.(i) in t.node.(i) <- t.node.(m); t.node.(m) <- tmp;
        max_heapify m
      end in
    max_heapify 1;
    ret

  let push x t =
    t.size <- t.size + 1;
    t.node.(t.size) <- x;
    let parent i = int_of_float (floor (float_of_int i) /. 2.) in
    let rec doit i =
      if i > 1 && M.compare t.node.(parent i) t.node.(i) < 0 then begin
        let tmp = t.node.(i) in t.node.(i) <- t.node.(parent i); t.node.(parent i) <- tmp;
        doit (parent i)
      end in
    doit t.size
end

module H = MakeBinaryHeap(struct type t = (int * int) let compare x y = fst x - fst y end)

let dijkstra g n =
  let h = H.make 100000 (0, 0) in
  let d = Array.make n max_int in
  let b = Array.make n false in
  d.(0) <- 0;
  b.(0) <- true;
  H.push (0, 0) h;
  let rec doit () =
    if not (H.empty_p h) then begin
      let (x, u) = H.pop h in
      b.(u) <- true;
      if d.(u) >= (-x) then duduwa u g.(u);
      doit ()
    end
  and duduwa u = function
    | [] -> ()
    | (v, _) :: tl when b.(v) = true -> duduwa u tl
    | (v, c) :: tl when d.(v) <= d.(u) + c -> duduwa u tl
    | (v, c) :: tl ->
      begin
        d.(v) <- d.(u) + c;
        H.push ((-d.(v)), v) h;
        duduwa u tl
      end in
  doit ();
  d

let rec make_pair acc = function
  | [] -> acc
  | f :: t :: tl -> make_pair ((f, t) :: acc) tl
  | _ -> exit 1

let () =
  let n = read_int () in
  let g = Array.make n [] in
  let rec read i =
    if i < n then
      match List.map int_of_string (Str.split (Str.regexp " ") (read_line ())) with
      | u :: _ :: l -> (g.(u) <- make_pair [] l; read (i + 1))
      | _ -> exit 1
  in read 0;
  Array.iteri (fun i e -> Printf.printf "%d %d\n" i e) (dijkstra g n)