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)

// AOJ GRL_1_A Shortest Path - Single Source Shortest Path
// 2018.4.26 bal4u

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define QMAX 150000
typedef struct { int t, s; } QUE;
QUE que[QMAX]; int qsize;

#define PARENT(i) ((i)>>1)
#define LEFT(i)   ((i)<<1)
#define RIGHT(i)  (((i)<<1)+1)

void min_heapify(int i)
{
	int l, r, min;
	QUE qt;

	l = LEFT(i), r = RIGHT(i);
	if (l < qsize && que[l].t < que[i].t) min = l; else min = i;
	if (r < qsize && que[r].t < que[min].t) min = r;
	if (min != i) {
		qt = que[i], que[i] = que[min], que[min] = qt;
		min_heapify(min);
	}
}

void deq()
{
	que[0] = que[--qsize];
	min_heapify(0);
}

void enq(int s, int t)
{
	int i, min;
	QUE qt;

	i = qsize++;
	que[i].s = s, que[i].t = t;
	while (i > 0 && que[min = PARENT(i)].t > que[i].t) {
		qt = que[i], que[i] = que[min], que[min] = qt;
		i = min;
	}
}

// バッファを経ずstdinから数値を得る
//#define getchar_unlocked()  getchar()
int in()
{
	int n = 0, c = getchar_unlocked();
	do n = 10*n + (c & 0xf), c = getchar_unlocked(); while (c >= '0');
	return n;
}

#define INF  0x70707070
#define MAX_V  100002
int V;  // 頂点数
int hi[MAX_V], *to[MAX_V], *d[MAX_V];
int dist[MAX_V];

void dijkstra(int start)
{
	int i, s, e, t, nt;

	memset(dist, INF, V<<2);
	qsize = 0;
	dist[start] = 0, enq(start, 0);
	while (qsize) {
		s = que[0].s, t = que[0].t, deq();
		if (dist[s] < t) continue;
		for (i = 0; i < hi[s]; i++) {
			e = to[s][i], nt = t + d[s][i];
			if (dist[e] > nt) dist[e] = nt, enq(e, nt);
		}
	}
}

int main()
{
	int E, r, i, j, k, s;
	int *memo;

	V = in(), E = in(), r = in();
	memo = malloc(sizeof(int)*3*E);
	j = 0; for (i = 0; i < E; i++) {
		memo[j++] = s = in(), hi[s]++;
		memo[j++] = in(), memo[j++] = in();
	}
	for (i = 0; i < V; i++) {
		if (hi[i]) to[i] = malloc(hi[i]<<2), d[i] = malloc(hi[i]<<2);
	}
	memset(hi, 0, V<<2);
	j = 0; while (E--) {
		s = memo[j++];
		k = hi[s]++, to[s][k] = memo[j++], d[s][k] = memo[j++];
	}
	dijkstra(r);
	for (i = 0; i < V; i++) {
		if (dist[i] == INF) puts("INF");
		else printf("%d\n", dist[i]);
	}
	return 0;
}