結果
| 問題 |
No.160 最短経路のうち辞書順最小
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2022-03-02 03:31:58 |
| 言語 | Rust (1.83.0 + proconio) |
| 結果 |
AC
|
| 実行時間 | 8 ms / 5,000 ms |
| コード長 | 4,281 bytes |
| コンパイル時間 | 16,428 ms |
| コンパイル使用メモリ | 378,060 KB |
| 実行使用メモリ | 5,376 KB |
| 最終ジャッジ日時 | 2024-07-08 11:08:03 |
| 合計ジャッジ時間 | 14,261 ms |
|
ジャッジサーバーID (参考情報) |
judge1 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 4 |
| other | AC * 26 |
コンパイルメッセージ
warning: unused import: `min`
--> src/main.rs:2:16
|
2 | use std::cmp::{min, Ordering, Reverse};
| ^^^
|
= note: `#[warn(unused_imports)]` on by default
warning: variable does not need to be mutable
--> src/main.rs:132:17
|
132 | let mut prev = Node { id: e.to, cost: node.cost + e.cost, next: Some(node.id) };
| ----^^^^
| |
| help: remove this `mut`
|
= note: `#[warn(unused_mut)]` on by default
ソースコード
use std::collections::binary_heap::BinaryHeap;
use std::cmp::{min, Ordering, Reverse};
macro_rules! input {
(source = $s:expr, $($r:tt)*) => {
let mut iter = $s.split_whitespace();
let mut next = || { iter.next().unwrap() };
input_inner!{next, $($r)*}
};
($($r:tt)*) => {
let stdin = std::io::stdin();
let mut bytes = std::io::Read::bytes(std::io::BufReader::new(stdin.lock()));
let mut next = move || -> String{
bytes
.by_ref()
.map(|r|r.unwrap() as char)
.skip_while(|c|c.is_whitespace())
.take_while(|c|!c.is_whitespace())
.collect()
};
input_inner!{next, $($r)*}
};
}
macro_rules! input_inner {
($next:expr) => {};
($next:expr, ) => {};
($next:expr, $var:ident : $t:tt $($r:tt)*) => {
let $var = read_value!($next, $t);
input_inner!{$next $($r)*}
};
}
macro_rules! read_value {
($next:expr, ( $($t:tt),* )) => {
( $(read_value!($next, $t)),* )
};
($next:expr, [ $t:tt ; $len:expr ]) => {
(0..$len).map(|_| read_value!($next, $t)).collect::<Vec<_>>()
};
($next:expr, chars) => {
read_value!($next, String).chars().collect::<Vec<char>>()
};
($next:expr, usize1) => {
read_value!($next, usize) - 1
};
($next:expr, $t:ty) => {
$next().parse::<$t>().expect("Parse error")
};
}
#[derive(Debug, Clone, Copy)]
struct Edge {
to: usize,
cost: i32,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
struct Node {
id: usize,
cost: i32,
next: Option<usize>,
}
#[derive(Debug)]
struct Graph {
nodes: Vec<Node>,
edges: Vec<Vec<Edge>>,
}
impl Graph {
fn new(n_nodes: usize) -> Self {
let mut nodes = Vec::with_capacity(n_nodes);
let edges = vec![Vec::new(); n_nodes];
for i in 0..n_nodes {
nodes.push(Node { id: i, cost: i32::MAX, next: None })
}
Self {
nodes,
edges,
}
}
fn add_edge(&mut self, from: usize, to: usize, cost: i32) {
self.edges[from].push(Edge { to, cost });
self.edges[to].push(Edge { to: from, cost });
}
}
impl PartialOrd<Self> for Node {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
match (self.next, other.next) {
(Some(sn), Some(on)) => { (self.cost, sn).partial_cmp(&(other.cost, on)) }
(_, _) => { self.cost.partial_cmp(&other.cost) }
}
}
}
impl Ord for Node {
fn cmp(&self, other: &Self) -> Ordering {
match (self.next, other.next) {
(Some(sn), Some(on)) => { (self.cost, sn).cmp(&(other.cost, on)) }
(_, _) => { self.cost.cmp(&other.cost) }
}
}
}
fn dijkstra(graph: &mut Graph, from: usize, to: usize) {
let mut heap = BinaryHeap::new();
heap.push(Reverse(Node { id: to, cost: 0, next: None }));
while let Some(Reverse(node)) = heap.pop() {
if graph.nodes[node.id] < node {
continue;
}
graph.nodes[node.id] = node;
if node.id == from {
break;
}
for e in &graph.edges[node.id] {
let mut prev = Node { id: e.to, cost: node.cost + e.cost, next: Some(node.id) };
if prev < graph.nodes[e.to] {
graph.nodes[e.to] = prev;
heap.push(Reverse(prev));
}
}
}
}
fn trace_path(graph: &Graph, from: usize) -> Vec<&Node> {
let mut path = Vec::new();
let mut node_id = from;
loop {
let node = &graph.nodes[node_id];
path.push(node);
if let Some(next_node_id) = node.next {
node_id = next_node_id;
} else {
break;
}
}
path
}
fn main() {
input! {
n: usize,
m: usize,
s: usize,
g: usize,
edges: [(usize, usize, i32); m]
}
let mut graph = Graph::new(n);
for (from, to, cost) in edges {
graph.add_edge(from, to, cost);
}
dijkstra(&mut graph, s, g);
let path = trace_path(&graph, s);
let answer = path.iter().map(|p| p.id.to_string()).collect::<Vec<_>>().join(" ");
println!("{}", answer);
}