結果

問題 No.177 制作進行の宮森あおいです!
コンテスト
ユーザー ngtkana
提出日時 2026-08-06 02:52:56
言語 Rust
(1.94.0 + proconio + num + itertools)
コンパイル:
/usr/bin/rustc_custom
実行:
./target/release/main
結果
AC  
実行時間 2 ms / 2,000 ms
+ 152µs
コード長 5,014 bytes
記録
記録タグの例:
初AC ショートコード 純ショートコード 純主流ショートコード 最速実行時間
コンパイル時間 18,091 ms
コンパイル使用メモリ 201,640 KB
実行使用メモリ 5,888 KB
最終ジャッジ日時 2026-08-06 02:53:17
合計ジャッジ時間 14,821 ms
ジャッジサーバーID
(参考情報)
judge2_0 / judge1_0
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 3
other AC * 13
権限があれば一括ダウンロードができます

ソースコード

diff #
raw source code

use std::collections::HashSet;

use crate::max_flow::MaxFlow;
use proconio::{input, marker::Usize1};

fn main() {
    input! {
        required: u64,
        left_len: usize,
        a: [u64; left_len],
        right_len: usize,
        b: [u64; right_len],
    }
    let mut counter = 0..;
    let left = vec_from_fn(left_len, |_| counter.next().unwrap());
    let right = vec_from_fn(right_len, |_| counter.next().unwrap());
    let source = counter.next().unwrap();
    let sink = counter.next().unwrap();

    let mut inst = MaxFlow::new();
    for (i, &a) in a.iter().enumerate() {
        inst.add_edge(source, left[i], a);
    }
    for (j, &b) in b.iter().enumerate() {
        inst.add_edge(right[j], sink, b);
    }
    for j in 0..right_len {
        input! {
            k: usize,
            skip: [Usize1; k],
        }
        let skip = skip.into_iter().collect::<HashSet<_>>();
        for i in 0..left_len {
            if !skip.contains(&i) {
                inst.add_edge(left[i], right[j], u64::MAX);
            }
        }
    }
    let (flow, _cut) = inst.solve(counter.start, source, sink);
    let ans = flow >= required;
    println!("{}", if ans { "SHIROBAKO" } else { "BANSAKUTSUKITA" });
}

fn vec_from_fn<T>(len: usize, f: impl FnMut(usize) -> T) -> Vec<T> {
    (0..len).map(f).collect()
}

// max_flow {{{
// https://ngtkana.github.io/ac-adapter-rs/max_flow/index.html
#[allow(unused_imports)]
#[allow(dead_code)]
mod max_flow {
    use std::collections::{BinaryHeap, VecDeque};
    #[derive(Default, Debug)]
    pub struct MaxFlow {
        pub edges: Vec<Edge>,
    }
    impl MaxFlow {
        pub fn new() -> Self {
            Self::default()
        }
        pub fn add_edge(&mut self, src: usize, tar: usize, cap: u64) {
            self.edges.push(Edge {
                src,
                tar,
                cap,
                flow: 0,
            });
            self.edges.push(Edge {
                src: tar,
                tar: src,
                cap,
                flow: cap,
            });
        }
        pub fn original_edges(&self) -> Vec<Edge> {
            self.edges.iter().step_by(2).copied().collect()
        }
        pub fn solve(&mut self, n: usize, source: usize, sink: usize) -> (u64, Vec<bool>) {
            let Self { edges } = self;
            let mut g = vec![vec![]; n];
            for (i, &e) in edges.iter().enumerate() {
                g[e.src].push(i);
            }
            let mut excess = vec![0; n];
            for &i in &g[source] {
                let y = edges[i].tar;
                let f = edges[i].cap - edges[i].flow;
                if y == source || f == 0 {
                    continue;
                }
                excess[y] += f;
                edges[i].flow += f;
                edges[i ^ 1].flow -= f;
            }
            let mut height = vec![n + 1; n];
            let mut queue = VecDeque::new();
            height[source] = n;
            height[sink] = 0;
            queue.push_back(sink);
            while let Some(x) = queue.pop_front() {
                for &i in &g[x] {
                    let y = edges[i].tar;
                    if y != sink && height[y] == n + 1 && edges[i].flow != 0 {
                        height[y] = height[x] + 1;
                        queue.push_back(y);
                    }
                }
            }
            let mut heap = (0..n)
                .filter(|&x| x != source && x != sink && excess[x] != 0)
                .map(|x| (height[x], x))
                .collect::<BinaryHeap<_>>();
            'pop: while let Some((_, x)) = heap.pop() {
                for &i in &g[x] {
                    let y = edges[i].tar;
                    if edges[i].flow == edges[i].cap || height[x] <= height[y] {
                        continue;
                    }
                    let f = excess[x].min(edges[i].cap - edges[i].flow);
                    if excess[y] == 0 && y != source && y != sink {
                        heap.push((height[y], y));
                    }
                    edges[i].flow += f;
                    edges[i ^ 1].flow -= f;
                    excess[x] -= f;
                    excess[y] += f;
                    if excess[x] == 0 {
                        continue 'pop;
                    }
                }
                assert!(excess[x] > 0);
                height[x] = g[x]
                    .iter()
                    .filter(|&&i| edges[i].flow < edges[i].cap)
                    .map(|&i| height[edges[i].tar])
                    .min()
                    .unwrap()
                    + 1;
                heap.push((height[x], x));
            }
            let cut = height.iter().map(|&h| h >= n).collect();
            let flow = excess[sink];
            (flow, cut)
        }
    }
    #[derive(Debug, Default, Clone, Copy, PartialEq)]
    pub struct Edge {
        pub src: usize,
        pub tar: usize,
        pub cap: u64,
        pub flow: u64,
    }
}
// }}}
0