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)

use std::cmp::Ordering;
use std::collections::BinaryHeap;
use std::io::*;
use std::str::FromStr;
use std::usize;

fn read<T: FromStr>() -> T {
    let stdin = stdin();
    let stdin = stdin.lock();
    let token: String = stdin
        .bytes()
        .map(|c| c.expect("filed to read char") as char)
        .skip_while(|c| c.is_whitespace())
        .take_while(|c| !c.is_whitespace())
        .collect();
    token.parse().ok().expect("failed to parse token")
}

#[derive(Copy, Clone, Eq, PartialEq)]
struct State {
    cost: usize,
    position: usize,
    pre_node: usize,
}

impl Ord for State {
    // Orderingは2つの値の比較結果(<. =, >)で、次の列挙体で定義されている
    /*
    pub enum Ordering {
        Less,
        Equal,
        Greater,
    }
    */
    fn cmp(&self, other: &State) -> Ordering {
        other
            .cost
            .cmp(&self.cost)
            .then_with(|| self.position.cmp(&other.position))
    }
}

impl PartialOrd for State {
    fn partial_cmp(&self, other: &State) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

#[derive(Clone)]
struct Edge {
    node: usize,
    cost: usize,
}

fn dijkstra(adj_list: &Vec<Vec<Edge>>, start: usize) -> Option<(usize, Vec<usize>)> {
    /*
    最短経路とその経路だけ知りたければmemoをtrueに
    各地点までの最短経路数を知りたければfalseにする
    */
    let mut dist: Vec<_> = vec![usize::MAX; adj_list.len()];
    let mut pre_nodes: Vec<_> = (0..adj_list.len()).map(|i| i).collect();
    let mut heap = BinaryHeap::new();

    dist[start] = 0;
    heap.push(State {
        cost: 0,
        position: start,
        pre_node: 0,
    });

    while let Some(State {
        cost,
        position,
        pre_node,
    }) = heap.pop()
    {
        if cost > dist[position] {
            continue;
        }
        pre_nodes[position] = pre_node;

        for edge in &adj_list[position] {
            let next = State {
                cost: cost + edge.cost,
                position: edge.node,
                pre_node: position,
            };
            if next.cost < dist[next.position] {
                heap.push(next);
                dist[next.position] = next.cost;
            }
        }
    }
    return Some((0, dist));
}

fn main() {
    let v: usize = read();
    let e: usize = read();
    let start: usize = read();
    let mut graph = vec![vec![]; v + 1];
    for _ in 0..e {
        let x: usize = read();
        let y: usize = read();
        let z: usize = read();
        graph[x].push(Edge { node: y, cost: z });
    }
    let result = dijkstra(&graph, start).unwrap();
    for i in 0..v {
        match result.1[i] {
            usize::MAX => println!("INF"),
            d => println!("{}", d),
        }
    }
}