Update solution for 최단경로 w/ id 56594288

Time: 128ms
MemUsage: 24840KB
This commit is contained in:
2024-08-29 16:22:05 +09:00
parent 62ee98f7f9
commit f344f37506

View 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();
}