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 Scala (judge verdict: Accepted)

import scala.io.StdIn.{readInt, readLine};
import scala.collection.mutable.PriorityQueue;

object Main {
    def main(args: Array[String]): Unit = {
        val n = readInt;
        val ig = new IntGraph(n);
        for (i <- (0 until n)) {
            val line = readLine.split(" ").map(_.toInt);
            val src = line(0);
            val dstNum = line(1);
            for (j <- (0 until dstNum)) {
                val dst = 2 + (2 * j);
                val cost = 2 + (2 * j) + 1;
                ig.add(src, line(dst), line(cost));
            }
        }
        ig.shortestPath(0).zipWithIndex.foreach { e => println("%d %d".format(e._2, e._1))};
    }
}

class IntGraph(size: Int) {
    val m: Array[List[(Int, Int)]] = new Array[List[(Int, Int)]](size).map(e => Nil);
    def add(src: Int, dst: Int, cost: Int): Unit = m(src) = (dst, cost) :: m(src);
    def shortestPath(start: Int): Array[Int] = {
        val stat = new Array[Int](size); // 0: 未追加, 1: 追加済み
        val dist = new Array[Int](size).map( e => Int.MaxValue);
        val pq = new PriorityQueue[(Int, Int)]()(Ordering.by((e: (Int, Int)) => e._2).reverse);
        var cnt = 0;
        
        dist(start) = 0;
        pq.enqueue((start, dist(start)));
        while (cnt < size && pq.isEmpty == false) {
            val (src, srcCost) = pq.dequeue;
            if (stat(src) != 1) {
                stat(src) = 1;
                cnt += 1;
                for ((dstIdx, dstCost) <- m(src)) {
                    val newCost = dstCost + srcCost;
                    if (stat(dstIdx) != 1 && newCost < dist(dstIdx)) {
                        dist(dstIdx) = newCost;
                        pq.enqueue((dstIdx, newCost));
                    }
                }
            }
        }
        dist;
    }
}