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(unused_imports)]
use std::cmp::{min,max};
use std::collections::BinaryHeap;

fn main() {
    let xs = read_vec_i64();
    let (v,e,r) = (xs[0] as usize, xs[1] as usize, xs[2] as usize);
    let mut adj = vec![vec![]; v];
    for _ in 0..e {
        let ys = read_vec_i64();
        let (s,t,d) = (ys[0] as usize, ys[1] as usize, ys[2]);
        adj[s].push((t,d));
    }
    let mut dists = vec![None; v];
    dists[r] = Some(0);
    let mut heap = BinaryHeap::new();
    heap.push((0,r));
    while let Some((md,s)) = heap.pop() {
        let d = -md;
        for &(t,dd) in &adj[s] {
            let nd = d + dd;
            if dists[t].is_none() || nd < dists[t].unwrap() {
                dists[t] = Some(nd);
                heap.push((-nd,t));
            }
        }
    }
    for d in dists {
        match d {
            Some(x) => println!("{}", x),
            None => println!("INF"),
        }
    }
}

#[allow(dead_code)]
fn read_line() -> String {
    let mut ret = String::new();
    std::io::stdin().read_line(&mut ret).ok();
    ret.pop();
    return ret;
}

#[allow(dead_code)]
fn read_i64() -> i64 {
    let ss = read_line();
    return ss.parse::<i64>().unwrap();
}

#[allow(dead_code)]
fn read_vec_i64() -> Vec<i64> {
    let mut res = vec![];
    let ss = read_line();
    for ts in ss.split_whitespace() {
        let x = ts.parse::<i64>().unwrap();
        res.push(x);
    }
    return res;
}