結果
| 問題 |
No.160 最短経路のうち辞書順最小
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2022-03-01 14:17:10 |
| 言語 | Rust (1.83.0 + proconio) |
| 結果 |
MLE
|
| 実行時間 | - |
| コード長 | 4,597 bytes |
| コンパイル時間 | 10,775 ms |
| コンパイル使用メモリ | 381,672 KB |
| 実行使用メモリ | 813,088 KB |
| 最終ジャッジ日時 | 2024-07-07 20:16:07 |
| 合計ジャッジ時間 | 13,904 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 4 |
| other | AC * 1 MLE * 1 -- * 24 |
コンパイルメッセージ
warning: unused import: `std::io`
--> src/main.rs:1:5
|
1 | use std::io;
| ^^^^^^^
|
= note: `#[warn(unused_imports)]` on by default
warning: unused import: `min`
--> src/main.rs:3:16
|
3 | use std::cmp::{min, Ordering, Reverse};
| ^^^
ソースコード
use std::io;
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)]
struct Node {
id: usize,
cost: i32,
prev: 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, prev: 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 Eq for Node {}
impl PartialEq<Self> for Node {
fn eq(&self, other: &Self) -> bool {
self.cost.eq(&other.cost)
}
}
impl PartialOrd<Self> for Node {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
self.cost.partial_cmp(&other.cost)
}
}
impl Ord for Node {
fn cmp(&self, other: &Self) -> Ordering {
self.cost.cmp(&other.cost)
}
}
fn dijkstra(graph: &mut Graph, from: usize, to: usize) {
let mut heap = BinaryHeap::new();
let mut visited = vec![false; graph.nodes.len()];
graph.nodes[from].cost = 0;
heap.push(Reverse(graph.nodes[from]));
loop {
if let Some(Reverse(node)) = heap.pop() {
visited[node.id] = true;
if node.id == to {
break;
}
for e in &graph.edges[node.id] {
if visited[e.to] {
continue;
}
if node.cost + e.cost < graph.nodes[e.to].cost {
graph.nodes[e.to].cost = node.cost + e.cost;
graph.nodes[e.to].prev = Some(node.id);
}
if let Some(prev_node_id) = graph.nodes[e.to].prev {
if node.cost + e.cost == graph.nodes[e.to].cost && node.id < prev_node_id {
graph.nodes[e.to].prev = Some(node.id);
}
heap.push(Reverse(graph.nodes[e.to]));
}
}
} else {
break;
}
}
}
fn backtrace_path(graph: &Graph, to: usize) -> Vec<&Node> {
let mut path = Vec::new();
let mut node_id = to;
loop {
let node = &graph.nodes[node_id];
path.push(node);
if let Some(prev_node_id) = node.prev {
node_id = prev_node_id;
} else {
break;
}
}
path.reverse();
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 = backtrace_path(&graph, g);
let answer = path.iter().map(|p| p.id.to_string()).collect::<Vec<_>>().join(" ");
println!("{}", answer);
}