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 JAVA (judge verdict: Memory Limit Exceeded)


import java.io.IOException;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.PriorityQueue;
import java.util.Scanner;


public class Main {
	
	public static class Node implements Comparable<Node>{
		int node, cost;

		private Node(int node, int cost) {
			super();
			this.node = node;
			this.cost = cost;
		}

		@Override
		public int compareTo(Node arg0) {
			return this.cost - arg0.cost;
		}
	}
	
	public static class Edge{
		int from, to, cost;

		private Edge(int to, int cost) {
			super();
			this.to = to;
			this.cost = cost;
		}
	}
	
	public static void main(String[] args) throws IOException {
		Scanner sc = new Scanner(System.in);
		
		final int n = sc.nextInt();
		
		HashMap<Integer, LinkedList<Edge>> edges = new HashMap<Integer, LinkedList<Edge>>(n);
		
		for(int i = 0; i < n; i++){
			final int from = sc.nextInt();
			final int k = sc.nextInt();
			
			if(k == 0){
				continue;
			}else{
				edges.put(from, new LinkedList<Edge>());
			}
			
			for(int j = 0; j < k; j++){
				final int to = sc.nextInt();
				final int cost = sc.nextInt();
				
				edges.get(from).add(new Edge(to, cost));
			}
		}
		
		//boolean[] contain = new boolean[n];
		PriorityQueue<Node> queue = new PriorityQueue<Node>();
		
		Node[] nodes = new Node[n];
		for(int i = 1; i < n; i++){
			nodes[i] = new Node(i, Integer.MAX_VALUE / 2 - 1);
		}
		nodes[0] = new Node(0, 0);
		//contain[0] = true;
		queue.add(nodes[0]);
		
		while(!queue.isEmpty()){
			Node node = queue.poll();
			
			if(!edges.containsKey(node.node)){
				continue;
			}
			
			for(Edge edge : edges.get(node.node)){
				if(nodes[edge.to].cost > node.cost + edge.cost){
					//System.out.println("updated " + edge.to + " " + (node.cost + edge.cost));
					nodes[edge.to].cost = node.cost + edge.cost;
					
					queue.add(nodes[edge.to]);
				}
			}
			
			//System.gc();
		}
		
		for(int i = 0; i < n; i++){
			System.out.println(i + " " + nodes[i].cost);
		}
	}
}