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

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
 
namespace Aoj.ALDS.Chapter12C
{
    public enum SortOrder
    {
        Asc,
        Desc,
    }
 
    public class PriorityQueue<T>
    where T : IComparable<T>
    {
        public int Count {
            get{ return _count; }
        }
 
        private T[] _heap;
        private int _count;
        private SortOrder _sortOrder;
 
        public PriorityQueue(SortOrder sortOrder = SortOrder.Asc, int initSize = 128)
        {
            _heap  = new T[initSize];
            _count = 0;
            _sortOrder = sortOrder;
        }
 
        public void Enqueue(T t)
        {
            int current = _count;
 
            _count++;
 
            ResizeIfNeeded();
 
            while (current > 0)
            {
                int parent = (current - 1) / 2;
                if (Compare(t, _heap[parent]) >= 0)
                    break;
                 
                 _heap[current] = _heap[parent];
                 current = parent;
            }
 
            _heap[current] = t;
        }
 
        public T Dequeue()
        {
            if (_count <= 0)
                throw new InvalidOperationException("");
 
            _count--;
 
            T ret = _heap[0];
            T t = _heap[_count];
            _heap[0] = t;
 
            int current = 0;
 
 
            while (current * 2 + 1 <= _count)
            {
                int left  = current * 2 + 1;
                int right = current * 2 + 2;
 
                if (right <= _count && Compare(_heap[left], _heap[right]) > 0)
                    left = right;
 
                if (Compare(t, _heap[left]) < 0)
                    break;
 
                _heap[current] = _heap[left];
                current = left;
            }
 
            _heap[current] = t;
            _heap[_count] = default(T);
 
            return ret;
        }
 
        public T Peek()
        {
            if (_count <= 0)
                throw new InvalidOperationException("");
            return _heap[0];
        }
 
        public void Clear()
        {
            while (_heap.Count() > 0)
            {
                Dequeue();
            }
        }
 
        public bool Contains(T t)
        {
            for (int i = 0; i < _count; i++)
            {
                if (t.Equals(_heap[i]))
                    return true;
            }
 
            return false;
        }
 
        public T[] ToArray()
        {
            var array = new T[_count];
            for (int i = 0; i < _count; i++)
            {
                array[i] = _heap[i];
            }
            return array;
        }
 
        private void ResizeIfNeeded()
        {
            if (_count > _heap.Length)
            {
                var newHeap = new T[_heap.Length * 2];
                for (int i = 0; i < _heap.Length; i++)
                {
                    newHeap[i] = _heap[i];
                }
                _heap = newHeap;
            }
        }
 
        private int Compare(T left, T right)
        {
            return (_sortOrder == SortOrder.Asc)
                ? left.CompareTo(right)
                : left.CompareTo(right) * -1;
        }
    }
 
    enum Color
    {
        WHITE, GRAY, BLACK
    }
 
    class Node : IComparable<Node>
    {
        public int V { get; set; }
        public int D { get; set; }
 
        public Node (int v, int d)
        {
            V = v;
            D = d;
        }
 
        public int CompareTo(Node other)
        {
            if (D != other.D)
                return D - other.D;
            else
                return V - other.V;
        }
    }
 
    class Program
    {
        /// <summary>
        /// ????????????????????????¢??????´???????????????????????§????s??????????????????????????????????????±??????????
        /// </summary>
        /// <param name="m">???°????????????£??\????????????¨??????</param>
        /// <param name="n">???????????????°???</param>
        /// <param name="s">??§???????</param>
        /// <returns></returns>
        public static int[] Dijkstra(List<Node>[] adj, int n, int s)
        {
            // ????????????????????\??????
            var pQueue = new PriorityQueue<Node>();
 
            // ??§????s??????v??????§????????°???????¢???
            var d = new int[n];
 
            // ??????v??????¢??´?¢???¶??????
            var c = new Color[n];
 
            // ????????´??????????????????????
            for (int i = 0; i < n; i++)
            {
                d[i] = Int32.MaxValue;
                c[i] = Color.WHITE;
            }
 
            d[s] = 0;
            pQueue.Enqueue(new Node(0, 0));
 
            while (pQueue.Count > 0)
            {
                Node current = pQueue.Dequeue();
 
                c[current.V] = Color.BLACK;
 
                // ??????§???PQ???push??????????????´?????????????¢??????§?????????????????£????°??????
                // (d[current.V] == current.D???????????¶???????????????????°?????????????????????)
                if (d[current.V] < current.D)
                    continue;
 
                foreach (var node in adj[current.V])
                {
                    if (c[node.V] != Color.BLACK && d[node.V] > current.D + node.D)
                        d[node.V] = current.D + node.D;
                        c[node.V] = Color.GRAY;
 
                        pQueue.Enqueue(new Node(node.V, current.D + node.D));
                }
            }
 
            return d;
        }
 
        public static void Solve()
        {
            int n = int.Parse(Console.ReadLine());
 
            // ?????????°????????????£??\????????????¨??????
            var adj = new List<Node>[n];
             
             
            for (int i = 0; i < n; i++)
            {
                adj[i] = new List<Node>();
                int[] input = Array.ConvertAll(Console.ReadLine().Split(' '), int.Parse);
 
                int u = input[0];
                for (int j = 2; j < input.Count(); j += 2)
                {
                    adj[u].Add(new Node(input[j], input[j+1]));
                }
            }
 
            int[] answer = Dijkstra(adj, n, 0);
            for (int i = 0; i < n; i++)
            {
                Console.WriteLine("{0} {1}", i, answer[i]);
            }
        }
 
        public static void Main()
        {
            // Console.SetIn(new System.IO.StreamReader("AlgorithmsAndDataStructures/Input/12_Graph_C_01.txt"));
            // var sw = new Stopwatch();
            // sw.Start();
 
            Solve();
 
            // Console.WriteLine("{0}ms", sw.ElapsedMilliseconds);
        }
    }
}