Update solution for 최단경로 w/ id 56594288
Time: 128ms MemUsage: 24840KB
This commit is contained in:
133
baekjoon/최단경로/solution_56594288.rs
Normal file
133
baekjoon/최단경로/solution_56594288.rs
Normal file
@@ -0,0 +1,133 @@
|
||||
use std::io::{self, Write, BufWriter, BufRead};
|
||||
use std::cmp::{Eq, PartialEq, Ord, PartialOrd, Ordering};
|
||||
use std::collections::{BinaryHeap, HashMap};
|
||||
|
||||
macro_rules! parse_line {
|
||||
($buff: ident, $($t: ty),+) => ({
|
||||
let mut line = String::new();
|
||||
$buff.read_line(&mut line).unwrap();
|
||||
let mut iter = line.split_whitespace();
|
||||
($(iter.next().unwrap().parse::<$t>().unwrap()),+)
|
||||
})
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct Node{
|
||||
visit : bool,
|
||||
distance : Option<u32>,
|
||||
neighbors : HashMap<usize, u32>,
|
||||
}
|
||||
|
||||
impl Node{
|
||||
fn new() -> Self{
|
||||
Self{
|
||||
visit : false,
|
||||
distance : None,
|
||||
neighbors : HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
fn add_edge(&mut self, idx : usize, weight : u32){
|
||||
if let Some(x) = self.neighbors.get_mut(&idx){
|
||||
if weight < *x {
|
||||
*x = weight;
|
||||
}
|
||||
} else {
|
||||
self.neighbors.insert(idx, weight);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct Graph(Vec<Node>);
|
||||
|
||||
#[derive(Eq, PartialEq, Debug)]
|
||||
struct QueueItem(usize, u32);
|
||||
|
||||
impl Ord for QueueItem {
|
||||
fn cmp(&self, other: &Self) -> Ordering {
|
||||
other.1.cmp(&self.1)
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialOrd for QueueItem {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
type PQueue = BinaryHeap<QueueItem>;
|
||||
|
||||
impl Graph {
|
||||
fn new(length : usize) -> Self{
|
||||
Self(vec![Node::new(); length])
|
||||
}
|
||||
|
||||
fn print(&self){
|
||||
let stdout = io::stdout();
|
||||
let mut out = BufWriter::new(stdout.lock());
|
||||
|
||||
for node in self.0.iter(){
|
||||
match node.distance {
|
||||
Some(d) => writeln!(out, "{}", d).unwrap(),
|
||||
None => writeln!(out, "INF").unwrap()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn dijkstra(&mut self, start : usize){
|
||||
let mut queue = PQueue::new();
|
||||
|
||||
self.0[start].distance = Some(0);
|
||||
queue.push(QueueItem(start, 0));
|
||||
|
||||
while let Some(QueueItem(idx, distance)) = queue.pop() {
|
||||
if self.0[idx].visit{
|
||||
continue;
|
||||
} else {
|
||||
self.0[idx].visit = true;
|
||||
}
|
||||
|
||||
for (to, weight) in self.0[idx].neighbors.clone().drain(){
|
||||
let new_d = distance + weight;
|
||||
let mut flag = false;
|
||||
|
||||
match self.0[to].distance {
|
||||
Some(x) => {
|
||||
if new_d < x {
|
||||
self.0[to].distance = Some(new_d);
|
||||
flag = true;
|
||||
}
|
||||
},
|
||||
None => {
|
||||
self.0[to].distance = Some(new_d);
|
||||
flag = true;
|
||||
}
|
||||
}
|
||||
|
||||
if flag {
|
||||
queue.push(QueueItem(to, new_d));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main(){
|
||||
let stdin = io::stdin();
|
||||
let mut lock_in = stdin.lock();
|
||||
|
||||
let (num_nodes, num_edges) : (usize, usize) = parse_line!(lock_in, usize, usize);
|
||||
let mut graph = Graph::new(num_nodes);
|
||||
|
||||
let start_node : usize = parse_line!(lock_in, usize);
|
||||
|
||||
for _i in 0..num_edges{
|
||||
let (idx1, idx2, weight) : (usize, usize, u32) = parse_line!(lock_in, usize, usize, u32);
|
||||
graph.0[idx1 - 1].add_edge(idx2 - 1, weight);
|
||||
}
|
||||
|
||||
graph.dijkstra(start_node - 1);
|
||||
graph.print();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user