結果

問題 No.807 umg tours
ユーザー niuezniuez
提出日時 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
権限があれば一括ダウンロードができます

ソースコード

diff #

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);
        }
    }
}
0