結果
問題 | No.807 umg tours |
ユーザー | niuez |
提出日時 | 2019-04-10 23:58:54 |
言語 | Rust (1.77.0 + proconio) |
結果 |
TLE
(最新)
AC
(最初)
|
実行時間 | - |
コード長 | 12,727 bytes |
コンパイル時間 | 14,782 ms |
コンパイル使用メモリ | 378,892 KB |
実行使用メモリ | 94,964 KB |
最終ジャッジ日時 | 2024-07-08 09:57:55 |
合計ジャッジ時間 | 41,495 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge3 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 23 ms
20,732 KB |
testcase_01 | AC | 26 ms
20,852 KB |
testcase_02 | AC | 26 ms
20,880 KB |
testcase_03 | AC | 25 ms
20,904 KB |
testcase_04 | AC | 24 ms
20,776 KB |
testcase_05 | AC | 25 ms
20,800 KB |
testcase_06 | AC | 27 ms
20,900 KB |
testcase_07 | AC | 23 ms
20,880 KB |
testcase_08 | AC | 52 ms
20,808 KB |
testcase_09 | AC | 52 ms
20,684 KB |
testcase_10 | AC | 51 ms
20,744 KB |
testcase_11 | AC | 2,343 ms
80,036 KB |
testcase_12 | AC | 2,212 ms
62,472 KB |
testcase_13 | AC | 2,956 ms
83,060 KB |
testcase_14 | AC | 1,006 ms
47,600 KB |
testcase_15 | AC | 849 ms
42,164 KB |
testcase_16 | AC | 3,235 ms
87,156 KB |
testcase_17 | AC | 3,931 ms
94,964 KB |
testcase_18 | AC | 3,961 ms
94,916 KB |
testcase_19 | TLE | - |
testcase_20 | AC | 1,918 ms
57,744 KB |
testcase_21 | AC | 2,701 ms
58,880 KB |
testcase_22 | AC | 654 ms
37,076 KB |
testcase_23 | AC | 443 ms
35,780 KB |
testcase_24 | AC | 977 ms
76,200 KB |
testcase_25 | AC | 3,747 ms
94,440 KB |
ソースコード
pub trait Zero { fn zero() -> Self; } impl Zero for usize { fn zero() -> Self { 0 } } impl Zero for u8 { fn zero() -> Self { 0 } } impl Zero for u16 { fn zero() -> Self { 0 } } impl Zero for u32 { fn zero() -> Self { 0 } } impl Zero for u64 { fn zero() -> Self { 0 } } impl Zero for isize { fn zero() -> Self { 0 } } impl Zero for i8 { fn zero() -> Self { 0 } } impl Zero for i16 { fn zero() -> Self { 0 } } impl Zero for i32 { fn zero() -> Self { 0 } } impl Zero for i64 { fn zero() -> Self { 0 } } pub trait IsNN {} impl IsNN for usize {} impl IsNN for u8 {} impl IsNN for u16 {} impl IsNN for u32 {} impl IsNN for u64 {} pub trait Property: Copy {} impl<P> Property for P where P: Copy {} pub trait ArbWeight: Property + std::ops::Add<Output=Self> + std::ops::Sub<Output=Self> + std::cmp::Ord { fn zero() -> Self; fn inf() -> Self; fn neg_inf() -> Self { unreachable!() } } pub trait NNegWeight: ArbWeight {} #[derive(Clone, Copy, PartialEq, Eq)] pub enum NNegW<W> where W: Zero + IsNN + std::ops::Add<Output=W> + std::ops::Sub<Output=W> + std::cmp::Ord + Copy { Inf, Some(W), } impl<W> std::ops::Add for NNegW<W> where W: Zero + IsNN + std::ops::Add<Output=W> + std::ops::Sub<Output=W> + std::cmp::Ord + Copy { type Output = Self; fn add(self, rhs: Self) -> Self { match self { NNegW::Inf => { NNegW::Inf } NNegW::Some(d) => { match rhs { NNegW::Inf => NNegW::Inf, NNegW::Some(d2) => NNegW::Some(d + d2), } } } } } impl<W> std::ops::Sub for NNegW<W> where W: Zero + IsNN + std::ops::Add<Output=W> + std::ops::Sub<Output=W> + std::cmp::Ord + Copy { type Output = Self; fn sub(self, rhs: Self) -> Self { match self { NNegW::Inf => { match rhs { NNegW::Inf => unreachable!(), _ => NNegW::Inf, } } NNegW::Some(d) => { match rhs { NNegW::Inf => unreachable!(), NNegW::Some(d2) => NNegW::Some(d - d2), } } } } } impl<W> std::cmp::PartialOrd for NNegW<W> where W: Zero + IsNN + std::ops::Add<Output=W> + std::ops::Sub<Output=W> + std::cmp::Ord + Copy { fn partial_cmp(&self, rhs: &Self) -> Option<std::cmp::Ordering> { Some(self.cmp(rhs)) } } impl<W> std::cmp::Ord for NNegW<W> where W: Zero + IsNN + std::ops::Add<Output=W> + std::ops::Sub<Output=W> + std::cmp::Ord + Copy { fn cmp(&self, rhs: &Self) -> std::cmp::Ordering { match self { NNegW::Inf => { match rhs { NNegW::Inf => unreachable!(), _ => std::cmp::Ordering::Greater, } } NNegW::Some(d) => { match rhs { NNegW::Inf => std::cmp::Ordering::Less, NNegW::Some(d2) => d.cmp(d2), } } } } } impl std::ops::Shl for NNegW<usize> { type Output = Self; fn shl(self, rhs: Self) -> Self { match rhs { NNegW::Some(r) => match self { NNegW::Some(d) => NNegW::Some(d.shl(r)), other => other, } _ => unreachable!(), } } } impl std::ops::Shr for NNegW<usize> { type Output = Self; fn shr(self, rhs: Self) -> Self { match rhs { NNegW::Some(r) => match self { NNegW::Some(d) => NNegW::Some(d.shr(r)), other => other, } _ => unreachable!(), } } } impl<W> ArbWeight for NNegW<W> where W: Zero + IsNN + std::ops::Add<Output=W> + std::ops::Sub<Output=W> + std::cmp::Ord + Copy { fn zero() -> Self { NNegW::Some(W::zero()) } fn inf() -> Self { NNegW::Inf } } impl<W> NNegWeight for NNegW<W> where W: Zero + IsNN + std::ops::Add<Output=W> + std::ops::Sub<Output=W> + std::cmp::Ord + Copy {} use std::ops::{ Index, IndexMut }; pub trait ID { fn id(&self) -> usize; } impl ID for usize { fn id(&self) -> usize { *self } } pub struct Properties<W: Copy> { vec: Vec<W> } impl<'a, I: ID, W: Copy> Index<&'a I> for Properties<W> { 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<W> { fn index_mut(&mut self, idx: &'a I) -> &mut Self::Output { &mut self.vec[idx.id()] } } impl<'a, W: Copy> Properties<W> { 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() } } pub trait Vertex: ID + Clone { } impl<V: ID + Clone> Vertex for V { } pub trait Edge { type VType: Vertex; fn from(&self) -> &Self::VType; fn to(&self) -> &Self::VType; } impl<V> Edge for (V, V) where V: Vertex { type VType = V; fn from(&self) -> &Self::VType { &self.0 } fn to(&self) -> &Self::VType { &self.1 } } impl<V, P> Edge for (V, V, P) where V: Vertex, P: Property { type VType = V; fn from(&self) -> &Self::VType { &self.0 } fn to(&self) -> &Self::VType { &self.1 } } pub trait AdjEdge<V, E>: ID where V: Vertex, E: Edge<VType=V> { fn from(&self) -> &V; fn to(&self) -> &V; fn edge(&self) -> &E; } pub trait Graph<'a, V, E, AE> where V: Vertex + 'a, E: Edge<VType=V> + 'a, AE: AdjEdge<V, E> { type AdjIter: std::iter::Iterator<Item=AE>; type EIter: std::iter::Iterator<Item=AE>; type VIter: std::iter::Iterator<Item=V>; fn add_edge(&mut self, e: E); fn delta(&'a self, v: &V) -> Self::AdjIter; fn edges(&'a self) -> Self::EIter; fn vertices(&'a self) -> Self::VIter; fn v_size(&self) -> usize; fn e_size(&self) -> usize; } pub trait Directed<'a, V, E, AE>: Graph<'a, V, E, AE> where V: Vertex + 'a, E: Edge<VType=V> + 'a, AE: AdjEdge<V, E> {} pub trait Undirected<'a, V, E, AE>: Graph<'a, V, E, AE> where V: Vertex + 'a, E: Edge<VType=V> + 'a, AE: AdjEdge<V, E> {} #[derive(Clone,Copy,Eq,PartialEq,Debug)] pub struct Eite(pub usize); pub struct DiAdjEdge<'a, E: Edge + 'a>(&'a E, usize); impl<'a, E: Edge + 'a> ID for DiAdjEdge<'a, E> { fn id(&self) -> usize { self.1 } } impl<'a, V, E> AdjEdge<V, E> for DiAdjEdge<'a, E> where V: Vertex, E: Edge<VType=V> + 'a { fn from(&self) -> &E::VType { self.0.from() } fn to(&self) -> &E::VType { self.0.to() } fn edge(&self) -> &E { self.0 } } pub struct AdjIter<'a, E: Edge + 'a> { iter: std::slice::Iter<'a, Eite>, edges: &'a Vec<E>, } impl<'a, E: Edge + 'a> std::iter::Iterator for AdjIter<'a, E> { type Item = DiAdjEdge<'a, E>; fn next(&mut self) -> Option<Self::Item> { match self.iter.next() { Some(ei) => { Some( DiAdjEdge(&self.edges[ei.0], ei.0) ) } None => { None } } } } pub struct EIter<'a, E: Edge + 'a> { i: usize, iter: std::slice::Iter<'a, E>, } impl<'a, E: Edge + 'a> std::iter::Iterator for EIter<'a, E> { type Item = DiAdjEdge<'a, E>; fn next(&mut self) -> Option<Self::Item> { match self.iter.next() { Some(e) => { let i = self.i; self.i += 1; Some(DiAdjEdge(&e, i)) } None => None } } } pub struct VIter<'a, V: Vertex + 'a> { iter: std::slice:: Iter<'a, Option<V>>, } impl<'a, V: Vertex + 'a> std::iter::Iterator for VIter<'a, V> { type Item = V; fn next(&mut self) -> Option<Self::Item> { while let Some(v) = self.iter.next() { if v.is_none() { continue; } else { return v.clone(); } } None } } pub struct DirectedGraph<V: Vertex, E: Edge<VType=V>> { n: usize, m: usize, g: Vec<Vec<Eite>>, es: Vec<E>, vs: Vec<Option<V>>, } impl<'a, V, E> Graph<'a,V,E,DiAdjEdge<'a, E>> for DirectedGraph<V,E> where V: Vertex + 'a, E: Edge<VType=V> + 'a { type AdjIter = AdjIter<'a, E>; type EIter = EIter<'a, E>; type VIter = VIter<'a, V>; fn add_edge(&mut self, e: E) { let ei = Eite(self.m); self.m += 1; self.g[e.from().id()].push(ei); self.vertex_regist(e.from().clone()); self.vertex_regist(e.to().clone()); self.es.push(e); } fn delta(&'a self, v: &V) -> Self::AdjIter { AdjIter { iter: self.g[v.id()].iter(), edges: &self.es } } fn edges(&'a self) -> Self::EIter { EIter { i: 0, iter: self.es.iter() } } fn vertices(&'a self) -> Self::VIter { VIter { iter: self.vs.iter() } } fn v_size(&self) -> usize { self.n } fn e_size(&self) -> usize { self.m } } impl<V: Vertex, E: Edge<VType=V>> DirectedGraph<V,E> { pub fn new(n: usize) -> Self { DirectedGraph { n: n, m: 0, g: vec![Vec::<Eite>::new(); n], es: Vec::new(), vs: vec![None; n], } } fn vertex_regist(&mut self, v: V) { let i = v.id(); self.vs[i] = match self.vs[v.id()].take() { Some(vv) => { assert!(vv.id() == v.id()); Some(vv) } None => { Some(v) } } } } impl<'a, V, E> Directed<'a, V, E, DiAdjEdge<'a, E>> for DirectedGraph<V, E> where V: Vertex + 'a, E: Edge<VType=V> + 'a {} pub fn scaling_dijkstra<'a, V, E, AE, G, F>(g: &'a G, s: &V, cost: F) -> Properties<NNegW<usize>> where V: Vertex + 'a, E: Edge<VType=V> + 'a, AE: AdjEdge<V, E>, G: Graph<'a, V, E, AE>, F: Fn(&E) -> NNegW<usize> { type W = NNegW<usize>; let n = g.v_size(); let mut dist = Properties::new(n, &W::zero()); let mut mw = W::zero(); for e in g.edges() { if mw < cost(e.edge()) { mw = cost(e.edge()); } } let logw = { let mut cnt = 0usize; while mw > W::zero() { mw = mw >> NNegW::Some(1); cnt += 1; } cnt }; for k in (0..logw+1).rev() { for v in g.vertices() { dist[&v] = dist[&v] << NNegW::Some(1); } let mut temp = Properties::new(n, &W::inf()); temp[s] = W::zero(); let mut heap = vec![Vec::new(); n]; heap[0].push(s.clone()); for d in 0..heap.len() { while let Some(v) = heap[d].pop() { if temp[&v] < NNegW::Some(d) { continue; } for e in g.delta(&v) { let c = (cost(e.edge()) >> NNegW::Some(k)) + dist[e.from()] - dist[e.to()]; if temp[e.from()] + c < temp[e.to()] && temp[e.from()] + c < NNegW::Some(heap.len()) { temp[e.to()] = temp[e.from()] + c; heap[d + match c { NNegW::Some(cc) => cc, _ => unreachable!() }].push(e.to().clone()); } } } } for v in g.vertices() { dist[&v] = dist[&v] + temp[&v]; } } 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, } } } fn main() { let mut s = String::new(); std::io::stdin().read_line(&mut s).unwrap(); let v:Vec<usize> = 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<usize> = 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 = scaling_dijkstra(&g, &Ver(0, VIP::Yet), |ep| NNegW::Some(ep.2)); for i in 0..n { let ans = res[&Ver(i, VIP::Yet)] + res[&Ver(i, VIP::Used)]; if let NNegW::Some(d) = ans { println!("{}", d); } } }