Problem:
Single Source Shortest Path

For a given weighted graph G(V, E) and a source r, find the source shortest path to each vertex from the source (SSSP: Single Source Shortest Path).

Input

An edge-weighted graph G (V, E) and the source r.

|V| |E| r
s0 t0 d0
s1 t1 d1
:
s|E|-1 t|E|-1 d|E|-1

|V| is the number of vertices and |E| is the number of edges in G. The graph vertices are named with the numbers 0, 1,..., |V|-1 respectively. r is the source of the graph.

si and ti represent source and target vertices of i-th edge (directed) and di represents the cost of the i-th edge.

Output

Print the costs of SSSP in the following format.

c0
c1
:
c|V|-1

The output consists of |V| lines. Print the cost of the shortest path from the source r to each vertex 0, 1, ... |V|-1 in order. If there is no path from the source to a vertex, print INF.

Constraints

1 ≤ |V| ≤ 100000

0 ≤ di ≤ 10000

0 ≤ |E| ≤ 500000

There are no parallel edges

There are no self-loops

Sample Input 1

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

Sample Output 1

0
1
3
4

Sample Input 2

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

Sample Output 2

3
0
2
INF

Solution in C# (judge verdict: Accepted)

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Xml;

namespace Capp
{
    public class PriorityQueue<T> where T : IComparable
    {
        private IComparer<T> _comparer = null;
        private int _type = 0;

        private T[] _heap;
        private int _sz = 0;

        private int _count = 0;

        /// <summary>
        /// Priority Queue with custom comparer
        /// </summary>
        public PriorityQueue(int maxSize, IComparer<T> comparer)
        {
            _heap = new T[maxSize];
            _comparer = comparer;
        }

        /// <summary>
        /// Priority queue
        /// </summary>
        /// <param name="maxSize">max size</param>
        /// <param name="type">0: asc, 1:desc</param>
        public PriorityQueue(int maxSize, int type = 0)
        {
            _heap = new T[maxSize];
            _type = type;
        }

        private int Compare(T x, T y)
        {
            if (_comparer != null) return _comparer.Compare(x, y);
            return _type == 0 ? x.CompareTo(y) : y.CompareTo(x);
        }

        public void Push(T x)
        {
            _count++;

            //node number
            var i = _sz++;

            while (i > 0)
            {
                //parent node number
                var p = (i - 1) / 2;

                if (Compare(_heap[p], x) <= 0) break;

                _heap[i] = _heap[p];
                i = p;
            }

            _heap[i] = x;
        }

        public T Pop()
        {
            _count--;

            T ret = _heap[0];
            T x = _heap[--_sz];

            int i = 0;
            while (i * 2 + 1 < _sz)
            {
                //children
                int a = i * 2 + 1;
                int b = i * 2 + 2;

                if (b < _sz && Compare(_heap[b], _heap[a]) < 0) a = b;

                if (Compare(_heap[a], x) >= 0) break;

                _heap[i] = _heap[a];
                i = a;
            }

            _heap[i] = x;

            return ret;
        }

        public int Count()
        {
            return _count;
        }

        public T Peek()
        {
            return _heap[0];
        }

        public bool Contains(T x)
        {
            for (int i = 0; i < _sz; i++) if (x.Equals(_heap[i])) return true;
            return false;
        }

        public void Clear()
        {
            while (this.Count() > 0) this.Pop();
        }

        public IEnumerator<T> GetEnumerator()
        {
            var ret = new List<T>();

            while (this.Count() > 0)
            {
                ret.Add(this.Pop());
            }

            foreach (var r in ret)
            {
                this.Push(r);
                yield return r;
            }
        }

        public T[] ToArray()
        {
            T[] array = new T[_sz];
            int i = 0;

            foreach (var r in this)
            {
                array[i++] = r;
            }

            return array;
        }
    }

    class Program
    {
        public enum En
        {
            a
            ,b
            ,c
            ,d
            ,e
            ,f
        }

        static List<long> GetLine()
        {
            return Console.ReadLine().Split(' ').Select(x => long.Parse(x)).ToList();
        }

        static void Put<T>(T o)
        {
            Console.WriteLine(o);
        }

        static long[] dx = new long[] { 0, 1, 0, -1 };
        static long[] dy = new long[] { 1, 0, -1, 0 };

        static void Main(string[] args)
        {
            var ver = GetLine();
            long v = ver[0],e = ver[1],r = ver[2];

            var es = new List<List<Tuple<long, long>>>();
            for(int i = 0;i < v; i++)
            {
                es.Add(new List<Tuple<long, long>>());
            }

            for (int i = 0; i < e; i++)
            {
                var std = GetLine();
                long s = std[0],t = std[1], a = std[2];
                es[(int)s].Add(Tuple.Create(t, a));
                //es[(int)t].Add(Tuple.Create(s, a));

            }

            var q = new PriorityQueue<Tuple<long, long>>((int)Math.Max(v, e));

            q.Push(Tuple.Create((long)0, r));

            var d = new List<long>();
            for (int i = 0; i < v; i++)
                d.Add(-1);
            while (q.Count() > 0)
            {
                var p = q.Pop();
                var cs = p.Item1; //現在のコスト
                var cu = p.Item2;

                if (d[(int)cu] != -1 && d[(int)cu] <= cs)
                    continue;
                d[(int)cu] = cs;

                foreach (var ve in es[(int)cu])
                {
                    var add = ve.Item2; // この辺のコスト
                    if (d[(int)ve.Item1] == -1 || d[(int)ve.Item1] > cs + add)
                    {
                        q.Push(Tuple.Create(cs + add, ve.Item1));
                    }
                }
            }

            for(int i = 0; i < v; i++)
            {
                if(d[i] == -1)
                {
                    Console.WriteLine("INF");
                }else
                    Console.WriteLine(d[i]);
            }

        }
    }

    public class Solve
    {
        readonly List<int>[] es = new List<int>[10];
        int n;
        int m;
        int res = 0;

        // 訪問管理
        readonly bool[] Visit = new bool[10];
        private void Rec(int x)
        {
            bool ok = true;
            for (int i = 0; i < n; i++)
            {
                if (!Visit[i])
                    ok = false;
            }
            // 全て訪問済みならok
            if (ok)
            {
                res++;
                return;
            }

            foreach (var v in es[x])
            {
                // 訪問済みならcontinue
                if (Visit[v]) continue;

                // 訪問済みにする
                Visit[v] = true;

                Rec(v);

                // 訪問解除する
                Visit[v] = false;
            }
        }

        public void S()
        {
            var nm = Console.ReadLine().Split(' ').Select(x => int.Parse(x)).ToArray();
            n = nm[0];
            m = nm[1];
            for (int i = 0; i < 10; i++)
            {
                es[i] = new List<int>();
            }
            for (int i = 0; i < m; i++)
            {
                var s = Console.ReadLine().Split(' ').Select(x => int.Parse(x)).ToArray();
                var a = s[0] - 1;
                var b = s[1] - 1;
                es[a].Add(b);
                es[b].Add(a);
            }
            // 頂点1を訪問する
            Visit[0] = true;
            Rec(0);
            Console.WriteLine(res);
        }
    }

    public class Test<T> : ITest<T>
    {
        public string S { get; set; }
    }

    public interface ITest<out T>
    {
        string S { get; set; }
    }

    struct c
    {
        public string s { get; set; }
        private dynamic _d;
        public dynamic d { get { return _d; }}
        public void Setd(dynamic d)
        {
            _d = d;
        }
    }
    class AsTest
    {
        internal async Task<int> AsyncMethod(int x)
        {
            var t1 = Task.Run(() =>
            {
                Thread.Sleep(10000);
                return 10 * x;
            });
            var res = await t1;
            Console.WriteLine($"asyncmethod {res}");


            return res;
        }

    }
}