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)

#include <stdio.h>
#include <stdlib.h>
#define MAX_NODES 500000
#define INF 1010001000

typedef struct edge {
    int to, cost;
    struct edge *next;
}edge;

typedef struct vertex {
    int value, edges;
    struct edge *head;
}vertex;

typedef struct pair {
    int f, s;
}pair;

vertex graph[MAX_NODES];
pair queue[MAX_NODES];
int sz, V, E, start;

pair pop(void);
void push(pair x);
void add_edge(int from, int to, int cost);
void dijkstra(int st);


int main(void)
{
    int i, s, t, d;
    pair a;
    scanf("%d %d %d", &V, &E, &start);
    for (i = 0; i < E; i++) {
        scanf("%d %d %d", &s, &t, &d);
        add_edge(s, t, d);
        queue[i].f = INF;
    }
    for (i = 0; i < V; i++) {
        graph[i].value = INF;
    }
    dijkstra(start);
    for (i = 0; i < V; i++) {
        if (graph[i].value == INF) {
            puts("INF");
        } else {
            printf("%d\n", graph[i].value);
        }
    }
    return 0;
}


void dijkstra(int st)
{
    int i, j, v;
    pair tmp;
    edge *now;
    //Queueの初期化
    for (i = 0; i < 100; i++) {
        queue[i].f = INF;
    }
    graph[st].value = 0;

    tmp.f = 0; tmp.s = st;
    push(tmp);

    while (queue[0].f != INF) {
        if (sz==0) {
            break;
        }
        tmp = pop();
        //printf("poped:%d %d\n", tmp.f, tmp.s);
        v = tmp.s;      //現在見ているノードの番号
        now = graph[v].head;
        if (graph[v].value < tmp.f) { 
            continue;
        }
        while (now != NULL) {
            if (graph[now->to].value > graph[v].value + now->cost) {
                graph[now->to].value = graph[v].value + now->cost;
                tmp.f = graph[now->to].value; tmp.s = now->to;
                push(tmp);
            }
            now = now->next;
        }
    }
}

void add_edge(int from, int to, int cost)
{
    //fromからtoへ辺を張る
    edge *new, *now = graph[from].head;
    new = (edge *)malloc(sizeof(edge));
    new->to = to;
    new->cost = cost;
    new->next = NULL;
    if (now == NULL) {
        graph[from].head = new;
    } else {
        while (now->next != NULL) {
            now = now->next;
        }
        now->next = new;
    }
    graph[from].edges++;
}

void push(pair x)
{
    int i = sz++, p;
    //queue[sz++] = x;
    while (i > 0) {
        p = (i - 1) / 2;
        if (queue[p].f <= x.f) {
            break;
        }
        queue[i].f = queue[p].f;
        queue[i].s = queue[p].s;
        i = p;
    }
    queue[i] = x;
}

pair pop(void)
{
    int i = 0, a, b;
    pair ans = queue[0], x = queue[--sz];
    //printf("sz:%d\n", sz);
    while (i * 2 + 1 < sz) {
        a = i * 2 + 1;
        b = i * 2 + 2;
        if (b < sz && queue[b].f < queue[a].f) { 
            a = b;
        }
        if (queue[a].f >= x.f) {
            break;
        }
        queue[i] = queue[a];
        i = a;
    }
    queue[i] = x;
    //queue[sz].f = INF;
    return ans;
}