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;
using System.IO;
using System.Linq;

namespace CompetitiveProgramming
{
  class PriorityQueue<T> where T : IComparable
  {
    const int MAX_SIZE = 100010;
    private T[] heap;
    public int Size { get; protected set; }

    public PriorityQueue()
    {
      heap = new T[MAX_SIZE];
    }

    public void Push(T x)
    {
      int i = Size++;

      while (i > 0)
      {
        int p = (i - 1) / 2;
        if (heap[p].CompareTo(x) <= 0)
        {
          break;
        }
        heap[i] = heap[p];
        i = p;
      }
      heap[i] = x;
    }

    public T Top()
    {
      return heap[0];
    }

    public void Pop()
    {
      T x = heap[--Size];

      int i = 0;
      while (i * 2 + 1 < Size)
      {
        int a = i * 2 + 1, b = i * 2 + 2;
        if (b < Size && heap[b].CompareTo(heap[a]) < 0)
        {
          a = b;
        }

        if (heap[a].CompareTo(x) >= 0)
        {
          break;
        }
        heap[i] = heap[a];
        i = a;
      }
      heap[i] = x;
    }
  }

  class Pair<T1, T2> : IComparable where T1 : IComparable
  {
    public T1 first { get; set; }
    public T2 second { get; set; }

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

    public int CompareTo(object obj)
    {
      if (obj == null)
      {
        return 1;
      }
      return first.CompareTo(((Pair<T1, T2>)obj).first);
    }
  }

  class Edge
  {
    public int start { get; set; }
    public int goal { get; set; }
    public int cost { get; set; }


    public Edge(int start, int goal, int cost)
    {
      this.start = start;
      this.goal = goal;
      this.cost = cost;
    }
  }

  class Dijkstra
  {
    const int INF = (int)(1e9) + 10;
    public int[] d { get; protected set; }

    /* ????????°V????????????edges?????????????????°???s??????????????¨??????d???s??????????????¢???????´?????????? */
    public Dijkstra(int V, ArrayList edges, int s) 
    {
      d = new int[V];
      PriorityQueue<Pair<int, int>> que = new PriorityQueue<Pair<int, int>>();

      for (int i = 0; i < V; i++)
      {
        d[i] = INF;
      }
      d[s] = 0;
      que.Push(new Pair<int, int>(0, s));

      while (que.Size > 0)
      {
        Pair<int, int> p = que.Top(); que.Pop();
        int v = p.second;
        if (d[v] < p.first)
        {
          continue;
        }

        for (int i = 0; i < ((ArrayList)edges[v]).Count; i++)
        {
          Edge e = (Edge)((ArrayList)edges[v])[i];  
          if (d[e.goal] > d[v] + e.cost)
          {
            d[e.goal] = d[v] + e.cost;
            que.Push(new Pair<int, int>(d[e.goal], e.goal));
          }
        }
      }
    }
  }

  class Solve
  {
    const int INF = (int)(1e9) + 10;

    private void Main()
    {
      int[] VEr = Console.ReadLine().Split().Select(int.Parse).ToArray();
      int V = VEr[0], E = VEr[1], r = VEr[2];
      ArrayList edges = new ArrayList();
      
      for (int i = 0; i < V; i++)
      {
        edges.Add(new ArrayList());
      }
      
      for (int i = 0; i < E; i++)
      {
        int[] std = Console.ReadLine().Split().Select(int.Parse).ToArray();
        int s = std[0], t = std[1], d = std[2];
        ((ArrayList)edges[s]).Add(new Edge(s, t, d));
      }
      Dijkstra dijkstra = new Dijkstra(V, edges, r);

      for (int i= 0; i < V; i++)
      {
        if (dijkstra.d[i] >= INF)
        {
          Console.WriteLine("INF");
        }
        else
        {
          Console.WriteLine(dijkstra.d[i]);
        }
      }
    }

    public Solve()
    {
      Console.SetOut(new StreamWriter(Console.OpenStandardOutput()) { AutoFlush = false });
      Main();
      Console.Out.Flush();
    }
  }

  class Program
  {
    static void Main(string[] args)
    {
      new Solve();
    }
  }
}