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)

#pragma warning disable

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Numerics;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

static class MainClass
{
    private static Scanner scanner;
    public static void Main(string[] args)
    {
        scanner = new Scanner();
        Solve();
        // for scanner bug
        scanner.Next();
    }

    private static void Solve()
    {
        var V = scanner.NextInt();
        var E = scanner.NextInt();
        var r = scanner.NextInt();
        var dijkstra = new Dijkstra(V);
        for (int i = 0; i < E; i++)
        {
            dijkstra.AddEdge(scanner.NextInt(), scanner.NextInt(), scanner.NextInt());
        }
        var distances = dijkstra.GetDistances(r);
        for (int i = 0; i < distances.Length; i++)
        {
            if (distances[i] == -1)
            {
                Console.WriteLine("INF");
            }
            else
            {
                Console.WriteLine(distances[i]);
            }
        }
    }


    class Dijkstra
    {
        private List<ComparablePair>[] adjacencyList;
        private bool isDirectedGraph;
        public Dijkstra(int capacity, bool isDirected = true)
        {
            adjacencyList = new List<ComparablePair>[capacity];
            for (int i = 0; i < capacity; i++)
            {
                adjacencyList[i] = new List<ComparablePair>();
            }
            isDirectedGraph = isDirected;
        }

        public void AddEdge(int from, int to, int cost)
        {
            adjacencyList[from].Add(new ComparablePair(to, cost));
            if (!isDirectedGraph)
            {
                adjacencyList[to].Add(new ComparablePair(from, cost));
            }
        }

        public int[] GetDistances(int start)
        {
            var distances = new int[adjacencyList.Length];
            for (int i = 0; i < adjacencyList.Length; i++)
            {
                distances[i] = -1;
            }
            distances[start] = 0;
            var visitedList = new HashSet<int>();
            var current = start;
            var pq = new Heap<ComparablePair>();
            pq.Push(new ComparablePair(start, 0));
            while (pq.Count > 0)
            {
                var vertex = pq.Pop();
                visitedList.Add(vertex.Index);
                var adjanctes = adjacencyList[vertex.Index];
                foreach (var candEdge in adjanctes)
                {
                    if (distances[candEdge.Index] > candEdge.Cost + vertex.Cost || distances[candEdge.Index] < 0)
                    {
                        distances[candEdge.Index] = candEdge.Cost + vertex.Cost;
                    }
                    if (!visitedList.Contains(candEdge.Index))
                    {
                        pq.Push(new ComparablePair(candEdge.Index, candEdge.Cost + vertex.Cost));
                    }
                }
            }
            return distances;
        }

        struct ComparablePair : IComparable<ComparablePair>
        {
            public int Index { get; set; }
            public int Cost { get; set; }
            public ComparablePair(int index, int cost)
            {
                Index = index;
                Cost = cost;
            }
            public int CompareTo(ComparablePair other)
            {
                return Cost.CompareTo(other.Cost);
            }
            public override string ToString()
            {
                return $"Index: {Index}, Cost: {Cost}";
            }
        }
    }

    class Heap<T> where T : IComparable<T>
    {
        private List<T> heapList;
        public Heap()
        {
            heapList = new List<T>();
        }
        public Heap(int capacity)
        {
            heapList = new List<T>(capacity);
        }
        public void Push(T item)
        {
            var index = heapList.Count;
            heapList.Add(item);
            while (true)
            {
                var parentInd = (index - 1) / 2;
                var parent = heapList[parentInd];
                if (parent.CompareTo(item) > 0)
                {
                    Exchange(parentInd, index);
                    index = parentInd;
                    continue;
                }
                break;
            }
        }
        public T Pop()
        {
            var lastInd = heapList.Count - 1;
            if (lastInd == 0)
            {
                var cur = heapList[0];
                heapList.RemoveAt(0);
                return cur;
            }
            else if (lastInd < 0)
            {
                throw new InvalidOperationException();
            }
            var ret = heapList[0];
            var msi = heapList[0] = heapList[lastInd];
            heapList.RemoveAt(lastInd--);
            var current = 0;
            while (true)
            {
                var child1 = current * 2 + 1;
                var child2 = current * 2 + 2;
                if (child1 > lastInd)
                {
                    return ret;
                }
                else if (child2 > lastInd)
                {
                    if (msi.CompareTo(heapList[child1]) > 0)
                    {
                        Exchange(current, child1);
                    }
                    return ret;
                }
                if (heapList[child1].CompareTo(heapList[child2]) > 0)
                {
                    if (msi.CompareTo(heapList[child2]) > 0)
                    {
                        Exchange(current, child2);
                        current = child2;
                        continue;
                    }
                }
                else
                {
                    if (msi.CompareTo(heapList[child1]) > 0)
                    {
                        Exchange(current, child1);
                        current = child1;
                        continue;
                    }
                }
                return ret;
            }

        }
        private void Exchange(int first, int second)
        {
            var sItem = heapList[second];
            heapList[second] = heapList[first];
            heapList[first] = sItem;
        }
        public int Count => heapList.Count;
    }

    private static int UpperBound<T>(this IEnumerable<T> list, T item) where T : IComparable<T> => UpperBound(list.ToList(), item);
    private static int LowerBound<T>(this IEnumerable<T> list, T item) where T : IComparable<T> => LowerBound(list.ToList(), item);

    private static int UpperBound<T>(this List<T> list, T item) where T : IComparable<T>
    {
        return list.BinarySearch(item, -1, list.Count, (first, second) => first.CompareTo(second) > 0);
    }

    private static int LowerBound<T>(this List<T> list, T item) where T : IComparable<T>
    {
        return list.BinarySearch(item, -1, list.Count, (first, second) => first.CompareTo(second) >= 0);
    }

    private static int BinarySearch<T>(this List<T> list, T item, int left, int right, Func<T, T, bool> isOkPredicate)
    {
        while (Math.Abs(right - left) > 1)
        {
            var mid = left + (right - left) / 2;
            if (isOkPredicate(list[mid], item))
            {
                right = mid;
            }
            else
            {
                left = mid;
            }
        }
        return right;
    }


    #region ライブラリ

    public static long ToInt64(this string str) => long.Parse(str);
    public static bool IsInt32(this string str)
    {
        var ou = 0;
        return int.TryParse(str, out ou);
    }
    public static int ToInt32(this string str) => str == "" ? 0 : int.Parse(str);
    public static double ToDouble(this string str) => double.Parse(str);
    public static BigInteger ToBigInteger(this string str) => BigInteger.Parse(str);
    public static List<string> SplittedStringToList(this string str) => str.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).ToList();
    public static List<int> SplittedStringToInt32List(this string str) => str.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).Select(x => int.Parse(x)).ToList();
    public static List<long> SplittedStringToInt64List(this string str) => str.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).Select(x => long.Parse(x)).ToList();
    public static List<BigInteger> SplittedStringToBigInteger(this string str) => str.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).Select(x => BigInteger.Parse(x)).ToList();
    public const int INF = int.MaxValue / 4;
    public const long LONGINF = long.MaxValue / 2;
    public const int Mod1e9 = 1000000007;
    public static List<int> ToCumulativeSumList(this List<int> list)
    {
        var ls = new List<int>();
        ls.Add(list[0]);
        var count = list.Count;
        for (int i = 1; i < count; i++)
        {
            ls.Add(list[i] + ls.Last());
        }
        return ls;
    }

    public static void PrintArray(long[,] array)
    {
        for (int i = 0; i < array.GetLength(0); i++)
        {
            var sb = new StringBuilder();
            for (int j = 0; j < array.GetLength(1); j++)
            {
                sb.Append(array[i, j]).Append(" ");
            }
            Console.WriteLine(sb.ToString().Trim());
        }
    }
    public static int Manhattan(int x1, int x2, int y1, int y2)
    {
        return Math.Abs(x1 - x2) + Math.Abs(y1 - y2);
    }

    public static int Manhattan(KeyValuePair<int, int> keyValuePair1, KeyValuePair<int, int> keyValuePair2)
    {
        return Manhattan(keyValuePair1.Key, keyValuePair2.Key, keyValuePair1.Value, keyValuePair2.Value);
    }

    public static T DeepClone<T>(this T src)
    {
        using (var memoryStream = new MemoryStream())
        {
            var binaryFormatter
              = new BinaryFormatter();
            binaryFormatter.Serialize(memoryStream, src);
            memoryStream.Seek(0, SeekOrigin.Begin);
            return (T)binaryFormatter.Deserialize(memoryStream);
        }
    }

    public static Dictionary<T, int> ToCountedDictionary<T>(this IEnumerable<T> items)
    {
        var dic = new Dictionary<T, int>();
        foreach (var item in items)
        {
            if (dic.ContainsKey(item))
                dic[item]++;
            else
                dic.Add(item, 1);
        }
        return dic;
    }
    public static Dictionary<TKey, TValue> KeyValuePairListToDictionary<TKey, TValue>(this IEnumerable<KeyValuePair<TKey, TValue>> pairs)
    {
        var dic = new Dictionary<TKey, TValue>();
        foreach (var item in pairs)
        {
            dic.Add(item.Key, item.Value);
        }
        return dic;
    }
    public class Scanner
    {
        private TextReader reader;
        public Scanner()
        {
            reader = Console.In;
        }
        public Scanner(TextReader reader)
        {
            this.reader = reader;
        }
        private string NextWord()
        {
            var sb = new StringBuilder();
            while (true)
            {
                var c = reader.Read();
                if ((c == 13 || c == 10 || c == 32) && sb.Length > 0 || c == -1)
                {
                    break;
                }
                sb.Append((char)c);
            }
            return sb.ToString().Trim();
        }
        public int NextInt() => NextWord().ToInt32();
        public string Next() => NextWord();
        public double NextDouble() => NextWord().ToDouble();
        public long NextLong() => NextWord().ToInt64();
        public BigInteger NextBigInteger() => NextWord().ToBigInteger();
        public string NextLine()
        {
            var str = reader.ReadLine();
            if (string.IsNullOrWhiteSpace(str))
            {
                return reader.ReadLine();
            }
            else
            {
                return str;
            }
        }
        private List<string> NextLineToList() => NextLine().Split(new char[] { ' ' },
                                                                  StringSplitOptions.RemoveEmptyEntries)
                                                           .ToList();
        public List<int> NextLineToIntList() => NextLineToList().Select(x => int.Parse(x))
                                                                .ToList();
    }
    public static long Sums(IEnumerable<int> list)
    {
        var sum = 0l;
        foreach (var item in list)
        {
            sum += Math.Abs(item);
        }
        return sum;
    }
    public static string IEnumerableListToString<T>(this IEnumerable<T> ls, bool withSpace = false)
    {
        var sb = new StringBuilder();
        foreach (var item in ls)
        {
            sb.Append(item);
            if (withSpace)
            {
                sb.Append(" ");
            }
        }
        return sb.ToString();
    }
    #endregion

    public static int[] dx = { -1, 1, 0, 0 };
    public static int[] dy = { 0, 0, 1, -1 };

    public static int[] dxx = { 0, 1, 1, 1, 0, -1, -1, -1 };
    public static int[] dyy = { 1, 1, 0, -1, -1, -1, 0, 1 };

}