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 Rust (judge verdict: Accepted)

#![allow(non_snake_case)]
#![allow(unused_variables)]
#![allow(dead_code)]

fn main() {
    let (_N, _M, r): (usize, usize, usize) = {
        let mut line: String = String::new();
        std::io::stdin().read_line(&mut line).unwrap();
        let mut iter = line.split_whitespace();
        (
            iter.next().unwrap().parse().unwrap(),
            iter.next().unwrap().parse().unwrap(),
            iter.next().unwrap().parse().unwrap()
        )
    };
    let (_A, _B, _C): (Vec<usize>, Vec<usize>, Vec<i64>) = {
        let (mut _A, mut _B, mut _C) = (vec![], vec![], vec![]);
        for _ in 0.._M {
            let mut line: String = String::new();
            std::io::stdin().read_line(&mut line).unwrap();
            let mut iter = line.split_whitespace();
            _A.push(iter.next().unwrap().parse().unwrap());
            _B.push(iter.next().unwrap().parse().unwrap());
            _C.push(iter.next().unwrap().parse().unwrap());
        }
        (_A, _B, _C)
    };
    // snip
    let _G = {
        let mut _G = vec![std::collections::HashMap::new(); _N + 1];
        for i in 0.._M { _G[_A[i]].insert(_B[i], _C[i]); }
        _G
    };
    // snip

    let V = _N;
    let E = _M;
    let s = _A;
    let t = _B;
    let d = _C;
    let G = _G;
    const INF: i64 = 1_000_000_000_000_000;
    let mut dp = vec![INF; V];
    let mut q = std::collections::BinaryHeap::new();
    q.push((0, r));
    while !q.is_empty() {
        let (dist, i) = {
            let (dist, i) = q.pop().unwrap();
            (-dist, i)
        };
        if dist < dp[i] {
            dp[i] = dist;
            for (&j, &w) in &G[i] { q.push((-(dist + w), j)); }
        }
    }
    let ans = dp.iter()
        .map(|&dist| if dist < INF { dist.to_string() } else { "INF".to_string() } )
        .collect::<Vec<_>>()
        .join("\n");

    println!("{}", ans);
}