結果

問題 No.1605 Matrix Shape
ユーザー atcoder8atcoder8
提出日時 2023-04-16 11:28:51
言語 Rust
(1.77.0 + proconio)
結果
WA  
実行時間 -
コード長 4,644 bytes
コンパイル時間 14,315 ms
コンパイル使用メモリ 378,240 KB
実行使用メモリ 66,628 KB
最終ジャッジ日時 2024-10-11 21:56:22
合計ジャッジ時間 19,413 ms
ジャッジサーバーID
(参考情報)
judge5 / judge3
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 0 ms
5,248 KB
testcase_01 AC 1 ms
5,248 KB
testcase_02 AC 1 ms
5,248 KB
testcase_03 WA -
testcase_04 AC 1 ms
5,248 KB
testcase_05 AC 1 ms
5,248 KB
testcase_06 WA -
testcase_07 AC 1 ms
5,248 KB
testcase_08 WA -
testcase_09 AC 1 ms
5,248 KB
testcase_10 WA -
testcase_11 WA -
testcase_12 WA -
testcase_13 AC 1 ms
5,248 KB
testcase_14 AC 1 ms
5,248 KB
testcase_15 WA -
testcase_16 WA -
testcase_17 AC 1 ms
5,248 KB
testcase_18 WA -
testcase_19 AC 286 ms
66,372 KB
testcase_20 WA -
testcase_21 WA -
testcase_22 AC 361 ms
65,876 KB
testcase_23 WA -
testcase_24 AC 393 ms
65,804 KB
testcase_25 WA -
testcase_26 WA -
testcase_27 WA -
testcase_28 AC 70 ms
26,752 KB
testcase_29 WA -
testcase_30 WA -
testcase_31 AC 189 ms
41,852 KB
testcase_32 WA -
testcase_33 AC 155 ms
33,492 KB
testcase_34 WA -
testcase_35 AC 264 ms
61,068 KB
testcase_36 AC 131 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();

    if scc.len() == 1 {
        println!("{}", n);
        std::process::exit(0);
    }

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

    let ans = visited.iter().all(|&x| x) as usize;
    println!("{}", ans);
}

/// 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