結果

問題 No.1605 Matrix Shape
ユーザー atcoder8atcoder8
提出日時 2023-04-16 11:31:02
言語 Rust
(1.77.0 + proconio)
結果
WA  
実行時間 -
コード長 4,608 bytes
コンパイル時間 13,471 ms
コンパイル使用メモリ 400,132 KB
実行使用メモリ 66,500 KB
最終ジャッジ日時 2024-10-11 21:58:49
合計ジャッジ時間 18,724 ms
ジャッジサーバーID
(参考情報)
judge3 / judge1
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 1 ms
5,248 KB
testcase_01 AC 1 ms
5,248 KB
testcase_02 AC 1 ms
5,248 KB
testcase_03 AC 1 ms
5,248 KB
testcase_04 AC 1 ms
5,248 KB
testcase_05 AC 1 ms
5,248 KB
testcase_06 AC 1 ms
5,248 KB
testcase_07 AC 1 ms
5,248 KB
testcase_08 AC 1 ms
5,248 KB
testcase_09 AC 1 ms
5,248 KB
testcase_10 WA -
testcase_11 WA -
testcase_12 AC 1 ms
5,248 KB
testcase_13 AC 1 ms
5,248 KB
testcase_14 WA -
testcase_15 WA -
testcase_16 WA -
testcase_17 AC 1 ms
5,248 KB
testcase_18 WA -
testcase_19 AC 389 ms
66,372 KB
testcase_20 AC 226 ms
42,608 KB
testcase_21 WA -
testcase_22 AC 355 ms
65,880 KB
testcase_23 AC 384 ms
66,500 KB
testcase_24 WA -
testcase_25 AC 70 ms
26,624 KB
testcase_26 AC 74 ms
26,880 KB
testcase_27 WA -
testcase_28 AC 70 ms
26,724 KB
testcase_29 WA -
testcase_30 AC 223 ms
41,840 KB
testcase_31 WA -
testcase_32 AC 163 ms
33,492 KB
testcase_33 AC 149 ms
33,308 KB
testcase_34 AC 48 ms
24,576 KB
testcase_35 AC 278 ms
60,944 KB
testcase_36 AC 144 ms
34,788 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

use atcoder8_library::scc::SCC;

fn main() {
    let n = {
        let mut line = String::new();
        std::io::stdin().read_line(&mut line).unwrap();
        line.trim().parse::<usize>().unwrap()
    };
    let mut hw = Vec::new();
    for _ in 0..n {
        hw.push({
            let mut line = String::new();
            std::io::stdin().read_line(&mut line).unwrap();
            let mut iter = line.split_whitespace();
            (
                iter.next().unwrap().parse::<usize>().unwrap() - 1,
                iter.next().unwrap().parse::<usize>().unwrap() - 1,
            )
        });
    }

    let values: Vec<usize> = hw
        .iter()
        .map(|x| x.0)
        .chain(hw.iter().map(|x| x.1))
        .collect();
    let (zip, unzip) = coordinate_compression(&values);

    let zip_hw: Vec<(usize, usize)> = (0..n).map(|i| (zip[i], zip[n + i])).collect();

    let mut graph = vec![vec![]; unzip.len()];
    for &(h, w) in &zip_hw {
        graph[h].push(w);
    }
    graph.iter_mut().for_each(|x| x.sort_unstable());

    let mut scc_graph = SCC::new(unzip.len());
    for &(h, w) in &zip_hw {
        scc_graph.add_edge(h, w);
    }

    let scc = scc_graph.scc();

    let mut visited = vec![false; unzip.len()];
    let mut stack = scc[0].clone();
    while let Some(cur) = stack.pop() {
        if visited[cur] {
            continue;
        }

        visited[cur] = true;

        for &next in &graph[cur] {
            stack.push(next);
        }
    }

    if visited.iter().all(|&x| x) {
        println!("{}", scc.last().unwrap().len());
    } else {
        println!("0");
    }
}

/// Performs coordinate compression of `seq`.
///
/// The return value is a tuple of `zip` and `unzip`.
/// `zip` is a list of the number of smallest values in the whole sequence for each element.
/// `unzip` is a list of the values that appear in the number sequence in ascending order.
/// The `i`-th element of the original sequence can be restored by `unzip[zip[i]]`.
pub fn coordinate_compression<T>(seq: &[T]) -> (Vec<usize>, Vec<T>)
where
    T: Clone + Ord,
{
    let mut unzip = seq.to_owned();
    unzip.sort_unstable();
    unzip.dedup();

    let zip: Vec<usize> = seq
        .iter()
        .map(|x| unzip.binary_search(x).unwrap())
        .collect();

    (zip, unzip)
}

pub mod atcoder8_library {
    pub mod scc {
        #[derive(Debug, Clone)]
        pub struct SCC {
            graph: Vec<Vec<usize>>,
            inv_graph: Vec<Vec<usize>>,
        }

        impl SCC {
            pub fn new(n: usize) -> Self {
                Self {
                    graph: vec![vec![]; n],
                    inv_graph: vec![vec![]; n],
                }
            }

            pub fn add_edge(&mut self, from: usize, to: usize) {
                self.graph[from].push(to);
                self.inv_graph[to].push(from);
            }

            pub fn scc(&self) -> Vec<Vec<usize>> {
                let n = self.graph.len();

                let mut order = vec![];
                let mut visited = vec![false; n];
                for start_node in 0..n {
                    if !visited[start_node] {
                        order.append(&mut post_order_traversal(
                            &self.graph,
                            &mut visited,
                            start_node,
                        ));
                    }
                }

                let mut scc = vec![];
                let mut visited = vec![false; n];
                for &start_node in order.iter().rev() {
                    if !visited[start_node] {
                        scc.push(post_order_traversal(
                            &self.inv_graph,
                            &mut visited,
                            start_node,
                        ));
                    }
                }

                scc
            }
        }

        fn post_order_traversal(
            graph: &Vec<Vec<usize>>,
            visited: &mut Vec<bool>,
            start_node: usize,
        ) -> Vec<usize> {
            let mut post_order = vec![];

            let mut stack = vec![(start_node, false)];

            while let Some((node, back)) = stack.pop() {
                if back {
                    post_order.push(node);
                }

                if visited[node] {
                    continue;
                }

                visited[node] = true;

                stack.push((node, true));

                stack.extend(graph[node].iter().map(|&next_node| (next_node, false)));
            }

            post_order
        }
    }
}
0