fn main() { let stdin = std::io::read_to_string(std::io::stdin().lock()).unwrap(); let mut stdin = stdin.split_ascii_whitespace(); unsafe { read!(stdin -> (n: u16, r: u16, c: u64, x: Vec[u32; n], y: Vec[u32; n], z: Vec[u32; n], s: Vec[u32; n], edges: Vec[(u32, u32, u32, u32, u32); r])); write!(output(solve(c, x, y, z, s, edges))); } } fn solve( c: u64, x: Vec, y: Vec, z: Vec, s: Vec, edges: Vec<(u32, u32, u32, u32, u32)>, ) -> u64 { let n = s.len(); let mut next_of = vec![Vec::new(); (n + 1) << 3]; next_of .chunks_exact_mut(1 << 3) .enumerate() .skip(1) .zip(x) .for_each(|((i, next_of), x)| { next_of .iter_mut() .enumerate() .filter(|&(j, _)| j & 1 == 0) .for_each(|(j, nexts)| nexts.push((((i << 3) | j | 1) as u32, x as u64))); }); next_of .chunks_exact_mut(1 << 3) .enumerate() .skip(1) .zip(y) .for_each(|((i, next_of), y)| { next_of .iter_mut() .enumerate() .filter(|&(j, _)| j & 2 == 0) .for_each(|(j, nexts)| nexts.push((((i << 3) | j | 2) as u32, y as u64))); }); next_of .chunks_exact_mut(1 << 3) .enumerate() .skip(1) .zip(z) .for_each(|((i, next_of), z)| { next_of .iter_mut() .enumerate() .filter(|&(j, _)| j & 4 == 0) .for_each(|(j, nexts)| nexts.push((((i << 3) | j | 4) as u32, z as u64))); }); next_of .chunks_exact_mut(1 << 3) .skip(1) .zip(s.iter()) .for_each(|(next_of, &s)| { next_of .iter_mut() .enumerate() .filter(|&(j, _)| j & 4 != 0) .for_each(|(j, nexts)| nexts.push((j as u32, s as u64 + c))); }); s.into_iter().enumerate().for_each(|(i, s)| { next_of .iter_mut() .enumerate() .take(1 << 3) .filter(|&(j, _)| j & 4 != 0) .for_each(|(j, nexts)| { nexts.push(((((i + 1) << 3) | j) as u32, s as u64)); }); }); edges.into_iter().for_each(|(u, v, w, a, m)| { next_of .iter_mut() .skip((u as usize) << 3) .take(1 << 3) .enumerate() .for_each(|(j, nexts)| { if j & 2 != 0 { nexts.push(((v << 3) | j as u32, w.min(a).min(m) as u64)); } else if j & 1 != 0 { nexts.push(((v << 3) | j as u32, w.min(a) as u64)); } else { nexts.push(((v << 3) | j as u32, w as u64)); } }); next_of .iter_mut() .skip((v as usize) << 3) .take(1 << 3) .enumerate() .for_each(|(j, nexts)| { if j & 2 != 0 { nexts.push((((u << 3) | j as u32), w.min(a).min(m) as u64)); } else if j & 1 != 0 { nexts.push(((u << 3) | j as u32, w.min(a) as u64)); } else { nexts.push(((u << 3) | j as u32, w as u64)); } }) }); let dist = mylib::dijkstra(next_of, [1 << 3].into_iter(), 0, u64::MAX); dist.into_iter().skip(n << 3).take(1 << 3).min().unwrap() } fn output(ans: u64) -> String { format!("{}", ans) } mod mylib { pub fn dijkstra + std::ops::Add>( next_of: Vec>, starts: impl Iterator, zero_cost: U, max_cost: U, ) -> Vec { use std::cmp::Reverse; let mut dist = vec![max_cost; next_of.len()]; let mut pq = starts .inspect(|&start| dist[start as usize] = zero_cost.clone()) .map(|start| Reverse((zero_cost.clone(), start))) .collect::>(); while let Some(Reverse((cur_dist, cur_pos))) = pq.pop() { if cur_dist == dist[cur_pos as usize] { next_of[cur_pos as usize].iter().for_each(|(next, cost)| { if dist[*next as usize] > cur_dist.clone() + cost.clone().into() { dist[*next as usize] = cur_dist.clone() + cost.clone().into(); pq.push(Reverse((cur_dist.clone() + cost.clone().into(), *next))); } }) } } dist } } #[macro_export] macro_rules! read { ($iter:ident -> ($v:ident : $t1:tt $([$($t2:tt)+] $({$($t3:tt)+})?)?)) => { let $v = read_value!($iter -> $t1 $([$($t2)+] $({$($t3)+})? )?); }; ($iter:ident -> ($v:ident : $t1:tt $([$($t2:tt)+] $({$($t3:tt)+})?)? , $($r:tt)*)) => { read!($iter -> ($v : $t1 $([$($t2)+] $({$($t3)+})?)?)); read!($iter -> ($($r)*)); }; } #[macro_export] macro_rules! read_value { ($source:ident -> ($($t1:tt $([$($t2:tt)+])?),+)) => { ( $(read_value!($source -> $t1 $([$($t2)+])?)),* ) }; ($source:ident -> [ $t1:tt ; $len:expr ]) => { { let mut x: [::std::mem::MaybeUninit<$t1>; $len] = ::std::mem::MaybeUninit::uninit().assume_init(); for elem in x.iter_mut() { elem.as_mut_ptr().write(read_value!($source -> $t1)); } ::std::mem::transmute::<[::std::mem::MaybeUninit<$t1>; $len], [$t1; $len]>(x) } }; ($source:ident -> [ $c2:tt [ $t1:tt $(; $len2:expr)? ] ; $len1:expr ]) => { { let mut x: [::std::mem::MaybeUninit<$c2<$t1>>; $len1] = unsafe { ::std::mem::MaybeUninit::uninit().assume_init() }; for elem in x.iter_mut() { elem.as_mut_ptr().write(read_value!($source -> $c2 [ $t1 $(; $len2)? ])); } ::std::mem::transmute::<[::std::mem::MaybeUninit<$c2<$t1>>; $len1], [$c2<$t1>; $len1]>(x) } }; ($source:ident -> $t1:tt[ $t2:tt $([$($t3:tt)+])? ; $len:expr ]) => { (0..($len)).map(|_| read_value!($source -> $t2 $([$($t3)+])?)).collect::<$t1<_>>() }; ($source:ident -> $t1:tt[ $t2:tt $([$($t3:tt)+])? ]) => { (0..(read_value!($source -> u32))).map(|_| read_value!($source -> $t2 $([$($t3)+])?)).collect::<$t1<_>>() }; ($source:ident -> $t1:tt[ ($($t2:tt),+) ; $len:expr ] { $($p1:pat => ($($pos:tt),*)),* }) => { (0..($len)).map(|_| { let mut v = ($($t2::default()),+); v.0 = my_parser::parse_without_checking(($source).next().unwrap()); match v.0 { $($p1 => { $(v.$pos = my_parser::parse_without_checking(($source).next().unwrap()));* }),* _ => unreachable!(), } v }).collect::<$t1<_>>() }; ($source:ident -> $t1:tt[ ($($t2:tt),+) ] { $($p1:pat => ($($pos:tt),*)),* }) => { read_value!($source -> $t1[ ($($t2),+) ; read_value!($source -> u32) ] { $($p1 => ($($pos),*)),* }) }; ($source:ident -> $t:ty) => { my_parser::parse_without_checking::<$t>(($source).next().unwrap()) }; } mod my_parser { #[allow(unused)] pub unsafe fn parse_without_checking(target: &str) -> F { unsafe { Parsable::from_str(target) } } pub trait Parsable { unsafe fn from_str(s: &str) -> Self; } impl Parsable for String { unsafe fn from_str(s: &str) -> Self { Self::from(s) } } impl Parsable for char { unsafe fn from_str(s: &str) -> Self { s.chars().next().unwrap() } } macro_rules! parse_float { ($s:ident) => {{ let mut iter = $s.bytes().peekable(); let sign = match iter.peek().unwrap() { b'-' => { iter.next(); -1.0 } b'+' => { iter.next(); 1.0 } _ => 1.0, }; let mut result = 0.0; while let Some(cur) = iter.next() && cur != b'.' { result = result * 10.0 + (cur - b'0') as Self; } let mut digit = 1.0; (result + iter .map(|cur| { digit *= 0.1; digit * (cur - b'0') as Self }) .sum::()) * sign }}; } impl Parsable for u8 { unsafe fn from_str(s: &str) -> Self { ((((s.bytes().fold(0, |acc, x| (acc << 8) | (x as u32)) & 0x0f0f0f0f) .wrapping_mul((1 << 8) + 10) >> 8) & 0x00ff00ff) .wrapping_mul((1 << 16) + 100) >> 16) as Self } } impl Parsable for u16 { unsafe fn from_str(s: &str) -> Self { ((((((s.bytes().fold(0, |acc, x| (acc << 8) | (x as u64)) & 0x0f0f0f0f0f0f0f0f) .wrapping_mul((1 << 8) + 10) >> 8) & 0x00ff00ff00ff00ff) .wrapping_mul((1 << 16) + 100) >> 16) & 0x0000ffff0000ffff) .wrapping_mul((1 << 32) + 10000) >> 32) as Self } } impl Parsable for u32 { unsafe fn from_str(s: &str) -> Self { ((((((((s.bytes().fold(0, |acc, x| (acc << 8) | (x as u128)) & 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f) .wrapping_mul((1 << 8) + 10) >> 8) & 0x00ff00ff00ff00ff00ff00ff00ff00ff) .wrapping_mul((1 << 16) + 100) >> 16) & 0x0000ffff0000ffff0000ffff0000ffff) .wrapping_mul((1 << 32) + 10000) >> 32) & 0x00000000ffffffff00000000ffffffff) .wrapping_mul((1 << 64) + 100000000) >> 64) as Self } } impl Parsable for u64 { unsafe fn from_str(s: &str) -> Self { const POW_10: [u64; 17] = [ 1, 10, 100, 1_000, 10_000, 100_000, 1_000_000, 10_000_000, 100_000_000, 1_000_000_000, 10_000_000_000, 100_000_000_000, 1_000_000_000_000, 10_000_000_000_000, 100_000_000_000_000, 1_000_000_000_000_000, 10_000_000_000_000_000, ]; s.as_bytes().chunks(16).fold(0, |acc, x| { acc * POW_10[x.len()] + ((((((((x.into_iter().fold(0, |acc, &x| (acc << 8) | (x as u128)) & 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f) .wrapping_mul((1 << 8) + 10) >> 8) & 0x00ff00ff00ff00ff00ff00ff00ff00ff) .wrapping_mul((1 << 16) + 100) >> 16) & 0x0000ffff0000ffff0000ffff0000ffff) .wrapping_mul((1 << 32) + 10000) >> 32) & 0x00000000ffffffff00000000ffffffff) .wrapping_mul((1 << 64) + 100000000) >> 64) as Self }) } } impl Parsable for u128 { unsafe fn from_str(s: &str) -> Self { const POW_10: [u128; 17] = [ 1, 10, 100, 1_000, 10_000, 100_000, 1_000_000, 10_000_000, 100_000_000, 1_000_000_000, 10_000_000_000, 100_000_000_000, 1_000_000_000_000, 10_000_000_000_000, 100_000_000_000_000, 1_000_000_000_000_000, 10_000_000_000_000_000, ]; s.as_bytes().chunks(16).fold(0, |acc, x| { acc * POW_10[x.len()] + ((((((((x.into_iter().fold(0, |acc, &x| (acc << 8) | (x as u128)) & 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f) .wrapping_mul((1 << 8) + 10) >> 8) & 0x00ff00ff00ff00ff00ff00ff00ff00ff) .wrapping_mul((1 << 16) + 100) >> 16) & 0x0000ffff0000ffff0000ffff0000ffff) .wrapping_mul((1 << 32) + 10000) >> 32) & 0x00000000ffffffff00000000ffffffff) .wrapping_mul((1 << 64) + 100000000) >> 64) as Self }) } } impl Parsable for i8 { unsafe fn from_str(s: &str) -> Self { ((((((s .bytes() .skip(match s.as_bytes()[0].is_ascii_digit() { true => 0, false => 1, }) .fold(0, |acc, x| (acc << 8) | (x as u32)) & 0x0f0f0f0f) .wrapping_mul((1 << 8) + 10) >> 8) & 0x00ff00ff) .wrapping_mul((1 << 16) + 100) >> 16) as i32) * match s.as_bytes()[0] == b'-' { true => -1, false => 1, }) as Self } } impl Parsable for i16 { unsafe fn from_str(s: &str) -> Self { ((((((((s .bytes() .skip(match s.as_bytes()[0].is_ascii_digit() { true => 0, false => 1, }) .fold(0, |acc, x| (acc << 8) | (x as u64)) & 0x0f0f0f0f0f0f0f0f) .wrapping_mul((1 << 8) + 10) >> 8) & 0x00ff00ff00ff00ff) .wrapping_mul((1 << 16) + 100) >> 16) & 0x0000ffff0000ffff) .wrapping_mul((1 << 32) + 10000) >> 32) as i64) * match s.as_bytes()[0] == b'-' { true => -1, false => 1, }) as Self } } impl Parsable for i32 { unsafe fn from_str(s: &str) -> Self { ((((((((((s .bytes() .skip(match s.as_bytes()[0].is_ascii_digit() { true => 0, false => 1, }) .fold(0, |acc, x| (acc << 8) | (x as u128)) & 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f) .wrapping_mul((1 << 8) + 10) >> 8) & 0x00ff00ff00ff00ff00ff00ff00ff00ff) .wrapping_mul((1 << 16) + 100) >> 16) & 0x0000ffff0000ffff0000ffff0000ffff) .wrapping_mul((1 << 32) + 10000) >> 32) & 0x00000000ffffffff00000000ffffffff) .wrapping_mul((1 << 64) + 100000000) >> 64) as i128) * match s.as_bytes()[0] == b'-' { true => -1, false => 1, }) as Self } } impl Parsable for i64 { unsafe fn from_str(s: &str) -> Self { const POW_10: [u64; 17] = [ 1, 10, 100, 1_000, 10_000, 100_000, 1_000_000, 10_000_000, 100_000_000, 1_000_000_000, 10_000_000_000, 100_000_000_000, 1_000_000_000_000, 10_000_000_000_000, 100_000_000_000_000, 1_000_000_000_000_000, 10_000_000_000_000_000, ]; let skip = match s.as_bytes()[0].is_ascii_digit() { true => 0, false => 1, }; ((s.as_bytes()[skip..].chunks(16).fold(0, |acc, x| { acc * POW_10[x.len()] + ((((((((x.into_iter().fold(0, |acc, &x| (acc << 8) | (x as u128)) & 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f) .wrapping_mul((1 << 8) + 10) >> 8) & 0x00ff00ff00ff00ff00ff00ff00ff00ff) .wrapping_mul((1 << 16) + 100) >> 16) & 0x0000ffff0000ffff0000ffff0000ffff) .wrapping_mul((1 << 32) + 10000) >> 32) & 0x00000000ffffffff00000000ffffffff) .wrapping_mul((1 << 64) + 100000000) >> 64) as u64 }) as i64) * match s.as_bytes()[0] == b'-' { true => -1, false => 1, }) as Self } } impl Parsable for i128 { unsafe fn from_str(s: &str) -> Self { const POW_10: [u128; 17] = [ 1, 10, 100, 1_000, 10_000, 100_000, 1_000_000, 10_000_000, 100_000_000, 1_000_000_000, 10_000_000_000, 100_000_000_000, 1_000_000_000_000, 10_000_000_000_000, 100_000_000_000_000, 1_000_000_000_000_000, 10_000_000_000_000_000, ]; let skip = match s.as_bytes()[0].is_ascii_digit() { true => 0, false => 1, }; ((s.as_bytes()[skip..].chunks(16).fold(0, |acc, x| { acc * POW_10[x.len()] + ((((((((x.into_iter().fold(0, |acc, &x| (acc << 8) | (x as u128)) & 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f) .wrapping_mul((1 << 8) + 10) >> 8) & 0x00ff00ff00ff00ff00ff00ff00ff00ff) .wrapping_mul((1 << 16) + 100) >> 16) & 0x0000ffff0000ffff0000ffff0000ffff) .wrapping_mul((1 << 32) + 10000) >> 32) & 0x00000000ffffffff00000000ffffffff) .wrapping_mul((1 << 64) + 100000000) >> 64) }) as i128) * match s.as_bytes()[0] == b'-' { true => -1, false => 1, }) as Self } } impl Parsable for f32 { unsafe fn from_str(s: &str) -> Self { parse_float!(s) } } impl Parsable for f64 { unsafe fn from_str(s: &str) -> Self { parse_float!(s) } } } #[macro_export] macro_rules! write { ($out:expr) => {{ use std::io::Write; std::io::stdout() .lock() .write_all(($out).as_bytes()) .unwrap(); }}; } #[macro_export] macro_rules! format_iter { ($i:expr, $sep:expr, ($($elem:ident),+) -> ($form:expr $(, $ex:expr)*)) => {{ #[allow(unused_parens)] let ($($elem),+) = i.next().unwrap(); #[allow(unused_parens)] $i.fold(std::format!($form $(, $ex)*), |mut acc, ($($elem),+)| { use std::fmt::Write; acc.push_str($sep); std::write!(&mut acc, $form $(, $ex)*).unwrap(); acc }) }} } #[macro_export] macro_rules! format_vec { ($v:expr, $sep:expr, ($($elem:ident),+) -> ($form:expr $(, $ex:expr)*)) => {{ if $v.is_empty() { String::new() } else { let mut v = $v; #[allow(unused_parens)] let ($($elem),+) = v.drain(..1).next().unwrap(); #[allow(unused_parens)] v.into_iter().fold(std::format!($form $(, $ex)*), |mut acc, ($($elem),+)| { use std::fmt::Write; acc.push_str($sep); std::write!(&mut acc, $form $(, $ex)*).unwrap(); acc }) } }} } #[macro_export] macro_rules! format_vec_vec { ($v:expr, $sep1:expr, $sep2:expr, ($($elem:ident),+) -> ($form:expr $(, $ex:expr)*)) => {{ let mut v = $v; let v_first = v.drain(..1).next().unwrap(); #[allow(unused_parens)] v.into_iter().fold(format_vec!(v_first, $sep2, ($($elem),+) -> ($form $(, $ex)*)), |mut acc, mut v| { use std::fmt::Write; acc.push_str($sep1); let ($($elem),+) = v.drain(..1).next().unwrap(); std::write!(&mut acc, $form $(, $ex)*).unwrap(); v.into_iter().fold(acc, |mut acc, ($($elem),+)| { acc.push_str($sep2); std::write!(&mut acc, $form $(, $ex)*).unwrap(); acc }) }) }} }