use std::ops::{Index, IndexMut}; pub trait Zero { fn zero() -> Self; } impl Zero for usize { fn zero() -> Self { 0 } } impl Zero for isize { fn zero() -> Self { 0 } } pub trait Property: Copy + Zero {} impl

Property for P where P: Copy + Zero {} pub trait Weight: Property + std::ops::Add + std::cmp::Ord {} impl Weight for W where W: Property + std::ops::Add + std::cmp::Ord {} pub trait NNWeight: Weight {} impl NNWeight for usize {} pub trait ID { fn id(&self) -> usize; } pub struct Properties { vec: Vec } impl<'a, I: ID, W: Copy> Index<&'a I> for Properties { type Output = W; fn index(&self, idx: &'a I) -> & Self::Output { &self.vec[idx.id()] } } impl<'a, I: ID, W: Copy> IndexMut<&'a I> for Properties { fn index_mut(&mut self, idx: &'a I) -> &mut Self::Output { &mut self.vec[idx.id()] } } impl<'a, W: Copy> Properties { pub fn new(n: usize, init: &W) -> Self { Properties { vec: vec![*init; n], } } pub fn iter(&'a self) -> std::slice::Iter<'a, W> { self.vec.iter() } } #[derive(Clone,Copy,Eq,PartialEq,Debug)] pub struct Eite(pub usize); pub trait Vertex: ID + Clone { } impl Vertex for V { } pub trait Edge { type VType: Vertex; fn from(&self) -> &Self::VType; fn to(&self) -> &Self::VType; } pub struct IEdge(E, usize); impl ID for IEdge { fn id(&self) -> usize { self.1 } } impl IEdge { pub fn from(&self) -> &E::VType { self.0.from() } pub fn to(&self) -> &E::VType { self.0.to() } pub fn edge(&self) -> &E { &self.0 } } pub struct AdjIter<'a, E: Edge + 'a> { iter: std::slice::Iter<'a, Eite>, edges: &'a Vec>, } impl<'a, E: Edge + 'a> std::iter::Iterator for AdjIter<'a, E> { type Item = &'a IEdge; fn next(&mut self) -> Option { match self.iter.next() { Some(ei) => { Some( &self.edges[ei.0] ) } None => { None } } } } pub trait Graph<'a, V, E>: where V: Vertex, E: Edge + 'a { fn add_edge(&mut self, e: E); fn delta(&'a self, v: &V) -> AdjIter; fn v_size(&self) -> usize; fn e_size(&self) -> usize; } pub struct DirectedGraph> { n: usize, m: usize, g: Vec>, es: Vec>, } impl<'a, V, E> Graph<'a,V,E> for DirectedGraph where V: Vertex, E: Edge + 'a { fn add_edge(&mut self, e: E) { let ei = Eite(self.m); self.m += 1; self.g[e.from().id()].push(ei); self.es.push(IEdge(e, ei.0)); } fn delta(&'a self, v: &V) -> AdjIter<'a, E> { AdjIter { iter: self.g[v.id()].iter(), edges: &self.es } } fn v_size(&self) -> usize { self.n } fn e_size(&self) -> usize { self.m } } impl> DirectedGraph { pub fn new(n: usize) -> Self { DirectedGraph { n: n, m: 0, g: vec![Vec::::new(); n], es: Vec::new(), } } } use std::collections::BinaryHeap; use std::cmp::Ordering; struct DijkstraNode { dist: Option, ver : V, } impl Ord for DijkstraNode { fn cmp(&self, other: &Self) -> Ordering { other.dist.cmp(&self.dist) } } impl PartialOrd for DijkstraNode { fn partial_cmp(&self, other: &Self) -> Option { Some(other.dist.cmp(&self.dist)) } } impl PartialEq for DijkstraNode { fn eq(&self, other: &Self) -> bool { self.dist == other.dist } } impl Eq for DijkstraNode { } pub fn dijkstra<'a, V, E, G, W, F>(g: &'a G, s: &V, cost: F) -> Properties> where V: Vertex, E: Edge + 'a, G: Graph<'a, V, E>, W: NNWeight, F: Fn(&E) -> W { let n = g.v_size(); let mut dist = Properties::new(n, &None); dist[s] = Some(W::zero()); let mut heap = BinaryHeap::new(); heap.push(DijkstraNode { dist: dist[s], ver: s.clone() }); while let Some(DijkstraNode { dist: Some(d), ver: v}) = heap.pop() { if let Some(now) = dist[&v] { if now < d { continue } } for e in g.delta(&v) { if match dist[e.to()] { Some(d2) => { cost(e.edge()) + d < d2 } None => true } { dist[e.to()] = Some(cost(e.edge()) + d); heap.push(DijkstraNode{ dist: dist[e.to()], ver: e.to().clone() }) } } } dist } // solution #[derive(Clone)] enum VIP { Yet, Used, } #[derive(Clone)] struct Ver(usize, VIP); impl ID for Ver { fn id(&self) -> usize { self.0 + match self.1 { VIP::Yet => 0, VIP::Used => 100000, } } } impl Edge for (Ver, Ver, usize) { type VType = Ver; fn from(&self) -> &Self::VType { &self.0 } fn to(&self) -> &Self::VType { &self.1 } } fn main() { let mut s = String::new(); std::io::stdin().read_line(&mut s).unwrap(); let v:Vec = s.trim().split_whitespace() .map(|e|e.parse().unwrap()).collect(); let (n, m) = (v[0] , v[1]); let mut g = DirectedGraph::new(200000); for _ in 0..m{ let mut t = String::new(); std::io::stdin().read_line(&mut t).unwrap(); let x:Vec = t.trim().split_whitespace() .map(|e|e.parse().unwrap()).collect(); let (v, u, d) = (x[0] - 1, x[1] - 1, x[2]); g.add_edge((Ver(v, VIP::Yet), Ver(u, VIP::Yet), d)); g.add_edge((Ver(v, VIP::Used), Ver(u, VIP::Used), d)); g.add_edge((Ver(v, VIP::Yet), Ver(u, VIP::Used), 0)); g.add_edge((Ver(u, VIP::Yet), Ver(v, VIP::Yet), d)); g.add_edge((Ver(u, VIP::Used), Ver(v, VIP::Used), d)); g.add_edge((Ver(u, VIP::Yet), Ver(v, VIP::Used), 0)); } g.add_edge((Ver(0, VIP::Yet), Ver(0, VIP::Used), 0)); let res = dijkstra(&g, &Ver(0, VIP::Yet), |ep| ep.2); for i in 0..n { println!("{}", res[&Ver(i, VIP::Yet)].unwrap() + res[&Ver(i, VIP::Used)].unwrap()); } }