結果
問題 | No.1813 Magical Stones |
ユーザー | nebocco |
提出日時 | 2021-11-25 13:17:01 |
言語 | Rust (1.77.0 + proconio) |
結果 |
AC
|
実行時間 | 68 ms / 2,000 ms |
コード長 | 11,930 bytes |
コンパイル時間 | 14,220 ms |
コンパイル使用メモリ | 384,156 KB |
実行使用メモリ | 19,912 KB |
最終ジャッジ日時 | 2024-07-16 08:07:00 |
合計ジャッジ時間 | 17,226 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge1 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 1 ms
6,812 KB |
testcase_01 | AC | 1 ms
6,816 KB |
testcase_02 | AC | 1 ms
6,944 KB |
testcase_03 | AC | 16 ms
10,524 KB |
testcase_04 | AC | 1 ms
6,944 KB |
testcase_05 | AC | 1 ms
6,940 KB |
testcase_06 | AC | 2 ms
6,940 KB |
testcase_07 | AC | 1 ms
6,944 KB |
testcase_08 | AC | 1 ms
6,940 KB |
testcase_09 | AC | 1 ms
6,940 KB |
testcase_10 | AC | 1 ms
6,944 KB |
testcase_11 | AC | 12 ms
6,944 KB |
testcase_12 | AC | 1 ms
6,940 KB |
testcase_13 | AC | 1 ms
6,940 KB |
testcase_14 | AC | 17 ms
10,524 KB |
testcase_15 | AC | 66 ms
18,292 KB |
testcase_16 | AC | 66 ms
18,420 KB |
testcase_17 | AC | 67 ms
19,912 KB |
testcase_18 | AC | 67 ms
18,292 KB |
testcase_19 | AC | 68 ms
18,288 KB |
testcase_20 | AC | 68 ms
18,292 KB |
testcase_21 | AC | 67 ms
18,288 KB |
testcase_22 | AC | 65 ms
18,296 KB |
testcase_23 | AC | 66 ms
18,288 KB |
testcase_24 | AC | 1 ms
6,940 KB |
testcase_25 | AC | 8 ms
6,940 KB |
testcase_26 | AC | 3 ms
6,944 KB |
testcase_27 | AC | 44 ms
12,748 KB |
testcase_28 | AC | 57 ms
16,628 KB |
testcase_29 | AC | 51 ms
15,032 KB |
testcase_30 | AC | 49 ms
14,476 KB |
testcase_31 | AC | 60 ms
16,676 KB |
testcase_32 | AC | 1 ms
6,940 KB |
testcase_33 | AC | 1 ms
6,944 KB |
testcase_34 | AC | 3 ms
6,940 KB |
testcase_35 | AC | 9 ms
6,940 KB |
testcase_36 | AC | 2 ms
6,940 KB |
testcase_37 | AC | 17 ms
6,944 KB |
testcase_38 | AC | 12 ms
7,596 KB |
testcase_39 | AC | 40 ms
12,004 KB |
testcase_40 | AC | 2 ms
6,940 KB |
testcase_41 | AC | 3 ms
6,944 KB |
testcase_42 | AC | 9 ms
6,940 KB |
testcase_43 | AC | 5 ms
6,940 KB |
ソースコード
fn main() { let mut io = IO::new(); input! { from io, n: usize, m: usize, mut edges: [(Usize1, Usize1); m] } assert!(2 <= n && n <= 100_000); assert!(m <= 200_000); for &(u, v) in &edges { assert!(u < n); assert!(v < n); assert_ne!(u, v); } edges.sort(); edges.dedup(); if edges.len() != m { eprintln!("多重辺あり") } let mut scc = SccGraph::new(n); for &(u, v) in &edges { scc.add_edge(u, v); } let grouping = scc.scc(); let n_group = grouping.len(); if n_group == 1 { io.println(0); return; } let mut ids = vec![0; n]; for (g, l) in grouping.iter().enumerate() { for &v in l.iter() { ids[v] = g; } } let mut new_in = vec![0; n_group]; let mut new_out = vec![0; n_group]; for &(u, v) in &edges { if ids[u] != ids[v] { new_out[ids[u]] += 1; new_in[ids[v]] += 1; } } let ans = new_in .iter() .filter(|&&x| x == 0) .count() .max(new_out.iter().filter(|&&x| x == 0).count()); io.println(ans); } use scc::SccGraph; pub mod scc { use crate::internal_scc; pub struct SccGraph { internal: internal_scc::SccGraph, } impl SccGraph { pub fn new(n: usize) -> Self { SccGraph { internal: internal_scc::SccGraph::new(n), } } pub fn add_edge(&mut self, from: usize, to: usize) { let n = self.internal.num_vertices(); assert!(from < n); assert!(to < n); self.internal.add_edge(from, to); } pub fn scc(&self) -> Vec<Vec<usize>> { self.internal.scc() } } } pub mod internal_scc { pub struct Csr<E> { start: Vec<usize>, elist: Vec<E>, } impl<E> Csr<E> where E: Copy, { pub fn new(n: usize, edges: &[(usize, E)], init: E) -> Self { let mut csr = Csr { start: vec![0; n + 1], elist: vec![init; edges.len()], }; for e in edges.iter() { csr.start[e.0 + 1] += 1; } for i in 1..=n { csr.start[i] += csr.start[i - 1]; } let mut counter = csr.start.clone(); for e in edges.iter() { csr.elist[counter[e.0]] = e.1; counter[e.0] += 1; } csr } } #[derive(Copy, Clone)] struct _Edge { to: usize, } /// Reference: /// R. Tarjan, /// Depth-First Search and Linear Graph Algorithms pub struct SccGraph { n: usize, edges: Vec<(usize, _Edge)>, } impl SccGraph { pub fn new(n: usize) -> Self { SccGraph { n, edges: vec![] } } pub fn num_vertices(&self) -> usize { self.n } pub fn add_edge(&mut self, from: usize, to: usize) { self.edges.push((from, _Edge { to })); } /// return pair of (# of scc, scc id) pub fn scc_ids(&self) -> (usize, Vec<usize>) { // In C++ ac-library, this function is implemented by using recursive lambda functions. // Instead, we use fn and struct for capturing environments. struct _Env { g: Csr<_Edge>, now_ord: usize, group_num: usize, visited: Vec<usize>, low: Vec<usize>, ord: Vec<Option<usize>>, ids: Vec<usize>, } let mut env = _Env { g: Csr::new(self.n, &self.edges, _Edge { to: 0 }), now_ord: 0, group_num: 0, visited: Vec::with_capacity(self.n), low: vec![0; self.n], ord: vec![None; self.n], ids: vec![0; self.n], }; fn dfs(v: usize, n: usize, env: &mut _Env) { env.low[v] = env.now_ord; env.ord[v] = Some(env.now_ord); env.now_ord += 1; env.visited.push(v); for i in env.g.start[v]..env.g.start[v + 1] { let to = env.g.elist[i].to; if let Some(x) = env.ord[to] { env.low[v] = std::cmp::min(env.low[v], x); } else { dfs(to, n, env); env.low[v] = std::cmp::min(env.low[v], env.low[to]); } } if env.low[v] == env.ord[v].unwrap() { loop { let u = *env.visited.last().unwrap(); env.visited.pop(); env.ord[u] = Some(n); env.ids[u] = env.group_num; if u == v { break; } } env.group_num += 1; } } for i in 0..self.n { if env.ord[i].is_none() { dfs(i, self.n, &mut env); } } for x in env.ids.iter_mut() { *x = env.group_num - 1 - *x; } (env.group_num, env.ids) } pub fn scc(&self) -> Vec<Vec<usize>> { let ids = self.scc_ids(); let group_num = ids.0; let mut counts = vec![0usize; group_num]; for &x in ids.1.iter() { counts[x] += 1; } let mut groups: Vec<Vec<usize>> = (0..ids.0).map(|_| vec![]).collect(); for i in 0..group_num { groups[i].reserve(counts[i]); } for i in 0..self.n { groups[ids.1[i]].push(i); } groups } } } // ------------ io module start ------------ use std::io::{stdout, BufWriter, Read, StdoutLock, Write}; pub struct IO { iter: std::str::SplitAsciiWhitespace<'static>, buf: BufWriter<StdoutLock<'static>>, } impl IO { pub fn new() -> Self { let mut input = String::new(); std::io::stdin().read_to_string(&mut input).unwrap(); let input = Box::leak(input.into_boxed_str()); let out = Box::new(stdout()); IO { iter: input.split_ascii_whitespace(), buf: BufWriter::new(Box::leak(out).lock()), } } fn scan_str(&mut self) -> &'static str { self.iter.next().unwrap() } pub fn scan<T: Scan>(&mut self) -> <T as Scan>::Output { <T as Scan>::scan(self) } pub fn scan_vec<T: Scan>(&mut self, n: usize) -> Vec<<T as Scan>::Output> { (0..n).map(|_| self.scan::<T>()).collect() } pub fn print<T: Print>(&mut self, x: T) { <T as Print>::print(self, x); } pub fn println<T: Print>(&mut self, x: T) { self.print(x); self.print("\n"); } pub fn iterln<T: Print, I: IntoIterator<Item = T>>(&mut self, iter: I, delim: &str) { let mut iter = iter.into_iter(); if let Some(v) = iter.next() { self.print(v); for v in iter { self.print(delim); self.print(v); } } self.print("\n"); } pub fn flush(&mut self) { self.buf.flush().unwrap(); } } impl Default for IO { fn default() -> Self { Self::new() } } pub trait Scan { type Output; fn scan(io: &mut IO) -> Self::Output; } macro_rules! impl_scan { ($($t:tt),*) => { $( impl Scan for $t { type Output = Self; fn scan(s: &mut IO) -> Self::Output { s.scan_str().parse().unwrap() } } )* }; } impl_scan!(i16, i32, i64, isize, u16, u32, u64, usize, String, f32, f64); impl Scan for char { type Output = char; fn scan(s: &mut IO) -> Self::Output { s.scan_str().chars().next().unwrap() } } pub enum Bytes {} impl Scan for Bytes { type Output = &'static [u8]; fn scan(s: &mut IO) -> Self::Output { s.scan_str().as_bytes() } } pub enum Chars {} impl Scan for Chars { type Output = Vec<char>; fn scan(s: &mut IO) -> Self::Output { s.scan_str().chars().collect() } } pub enum Usize1 {} impl Scan for Usize1 { type Output = usize; fn scan(s: &mut IO) -> Self::Output { s.scan::<usize>().wrapping_sub(1) } } impl<T: Scan, U: Scan> Scan for (T, U) { type Output = (T::Output, U::Output); fn scan(s: &mut IO) -> Self::Output { (T::scan(s), U::scan(s)) } } impl<T: Scan, U: Scan, V: Scan> Scan for (T, U, V) { type Output = (T::Output, U::Output, V::Output); fn scan(s: &mut IO) -> Self::Output { (T::scan(s), U::scan(s), V::scan(s)) } } impl<T: Scan, U: Scan, V: Scan, W: Scan> Scan for (T, U, V, W) { type Output = (T::Output, U::Output, V::Output, W::Output); fn scan(s: &mut IO) -> Self::Output { (T::scan(s), U::scan(s), V::scan(s), W::scan(s)) } } pub trait Print { fn print(w: &mut IO, x: Self); } macro_rules! impl_print_int { ($($t:ty),*) => { $( impl Print for $t { fn print(w: &mut IO, x: Self) { w.buf.write_all(x.to_string().as_bytes()).unwrap(); } } )* }; } impl_print_int!(i16, i32, i64, isize, u16, u32, u64, usize, f32, f64); impl Print for u8 { fn print(w: &mut IO, x: Self) { w.buf.write_all(&[x]).unwrap(); } } impl Print for &[u8] { fn print(w: &mut IO, x: Self) { w.buf.write_all(x).unwrap(); } } impl Print for &str { fn print(w: &mut IO, x: Self) { w.print(x.as_bytes()); } } impl Print for String { fn print(w: &mut IO, x: Self) { w.print(x.as_bytes()); } } impl<T: Print + Copy> Print for &T { fn print(w: &mut IO, x: Self) { w.print(*x); } } impl<T: Print, U: Print> Print for (T, U) { fn print(w: &mut IO, (x, y): Self) { w.print(x); w.print(" "); w.print(y); } } impl<T: Print, U: Print, V: Print> Print for (T, U, V) { fn print(w: &mut IO, (x, y, z): Self) { w.print(x); w.print(" "); w.print(y); w.print(" "); w.print(z); } } pub mod neboccoio_macro { #[macro_export] macro_rules! input { (@start $io:tt @read @rest) => {}; (@start $io:tt @read @rest, $($rest: tt)*) => { input!(@start $io @read @rest $($rest)*) }; (@start $io:tt @read @rest mut $($rest:tt)*) => { input!(@start $io @read @mut [mut] @rest $($rest)*) }; (@start $io:tt @read @rest $($rest:tt)*) => { input!(@start $io @read @mut [] @rest $($rest)*) }; (@start $io:tt @read @mut [$($mut:tt)?] @rest $var:tt: [[$kind:tt; $len2: expr]; $len1:expr] $($rest:tt)*) => { let $($mut)* $var = (0..$len1).map(|_| $io.scan_vec::<$kind>($len2)).collect::<<$kind as Scan>::Output>(); input!(@start $io @read @rest $($rest)*) }; (@start $io:tt @read @mut [$($mut:tt)?] @rest $var:tt: [$kind:tt; $len:expr] $($rest:tt)*) => { let $($mut)* $var = $io.scan_vec::<$kind>($len); input!(@start $io @read @rest $($rest)*) }; (@start $io:tt @read @mut [$($mut:tt)?] @rest $var:tt: $kind:tt $($rest:tt)*) => { let $($mut)* $var = $io.scan::<$kind>(); input!(@start $io @read @rest $($rest)*) }; (from $io:tt $($rest:tt)*) => { input!(@start $io @read @rest $($rest)*) }; } } // ------------ io module end ------------