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

Single Source Shortest Path

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 100$

$0 \leq c_i \leq 100,000$

$|E| \leq 10,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: Accepted)

import java.util.Scanner;
import java.util.Set;
import java.util.HashSet;
import java.util.Queue;
import java.util.ArrayDeque;
import java.util.Stack;
import java.util.PriorityQueue;

import static java.lang.System.out;

public class Main {
    private static final int INF = (int)1e9;

    static class Vertex {
        int v;
        Set<Integer> vs;

        public Vertex(int v) {
            this.v = v;
            this.vs = new HashSet<>();
        }
    }

    static class Pair {
        int first;
        int second;

        public Pair(int first, int second) {
            this.first = first;
            this.second = second;
        }

        @Override
        public boolean equals(Object other) {
            if (other != null && other instanceof Pair) {
                Pair p = (Pair)other;
                return p.first == first && p.second == second;
            }
            return false;
        }

        @Override
        public int hashCode() {
            int hash = 17;
            hash += hash*31 + first;
            hash += hash*31 + second;

            return hash;
        }
    }

	public static void main(String[] args) {
		try (Scanner in = new Scanner(System.in)) {
            int n = in.nextInt();
            Vertex[] g = new Vertex[n];
            for (int i = 0; i < n; i++) 
                g[i] = new Vertex(i);

            int[][] ws = new int[n][n];
            for (int i = 0; i < n; i++) {
                int f = in.nextInt();
                int d = in.nextInt();

                for (int j = 0; j < d; j++) {
                    int t = in.nextInt();
                    int w = in.nextInt();

                    g[f].vs.add(t);
                    ws[f][t] = w;
                }
            }

            dijkstra(g, n, ws, 0);
		} catch (Exception ex) {
			throw new RuntimeException(ex);
		}
	}

    private static void dijkstra(Vertex[] g, int n, int[][] ws, int s) {
        int[][] d = new int[n][2];
        for (int i = 0; i < n; i++) {
            d[i][0] = INF;
            d[i][1] = -1;
        }

        d[s][0] = 0;
        d[s][1] = s;
        PriorityQueue<Pair> pq = new PriorityQueue<>((x, y) -> Integer.compare(x.second, y.second));
        pq.add(new Pair(s, 0));

        while (!pq.isEmpty()) {
            Pair p = pq.poll();
            
            for (int vv : g[p.first].vs) {
                int nd = d[p.first][0] + ws[p.first][vv];
                if (nd < d[vv][0]) {
                    Pair pp = new Pair(vv, d[vv][0]);
                    d[vv][0] = nd;
                    d[vv][1] = p.first;
                    pq.remove(pp);
                    pq.add(new Pair(vv, d[vv][0]));
                }    
            }
        }

        for (int i = 0; i < n; i++)
            out.printf("%d %d\n", i, d[i][0]);
    }
}