結果

問題 No.1288 yuki collection
ユーザー fukafukatanifukafukatani
提出日時 2021-01-03 21:39:29
言語 Rust
(1.77.0)
結果
AC  
実行時間 153 ms / 5,000 ms
コード長 5,366 bytes
コンパイル時間 1,448 ms
コンパイル使用メモリ 173,948 KB
実行使用メモリ 5,376 KB
最終ジャッジ日時 2024-04-21 16:37:33
合計ジャッジ時間 5,418 ms
ジャッジサーバーID
(参考情報)
judge4 / judge1
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 1 ms
5,248 KB
testcase_01 AC 1 ms
5,376 KB
testcase_02 AC 1 ms
5,376 KB
testcase_03 AC 1 ms
5,376 KB
testcase_04 AC 1 ms
5,376 KB
testcase_05 AC 1 ms
5,376 KB
testcase_06 AC 1 ms
5,376 KB
testcase_07 AC 1 ms
5,376 KB
testcase_08 AC 1 ms
5,376 KB
testcase_09 AC 1 ms
5,376 KB
testcase_10 AC 1 ms
5,376 KB
testcase_11 AC 1 ms
5,376 KB
testcase_12 AC 1 ms
5,376 KB
testcase_13 AC 147 ms
5,376 KB
testcase_14 AC 141 ms
5,376 KB
testcase_15 AC 115 ms
5,376 KB
testcase_16 AC 117 ms
5,376 KB
testcase_17 AC 140 ms
5,376 KB
testcase_18 AC 149 ms
5,376 KB
testcase_19 AC 151 ms
5,376 KB
testcase_20 AC 147 ms
5,376 KB
testcase_21 AC 109 ms
5,376 KB
testcase_22 AC 110 ms
5,376 KB
testcase_23 AC 110 ms
5,376 KB
testcase_24 AC 153 ms
5,376 KB
testcase_25 AC 151 ms
5,376 KB
testcase_26 AC 146 ms
5,376 KB
testcase_27 AC 59 ms
5,376 KB
testcase_28 AC 76 ms
5,376 KB
testcase_29 AC 87 ms
5,376 KB
testcase_30 AC 4 ms
5,376 KB
testcase_31 AC 6 ms
5,376 KB
testcase_32 AC 6 ms
5,376 KB
testcase_33 AC 94 ms
5,376 KB
testcase_34 AC 86 ms
5,376 KB
testcase_35 AC 79 ms
5,376 KB
testcase_36 AC 92 ms
5,376 KB
testcase_37 AC 93 ms
5,376 KB
testcase_38 AC 26 ms
5,376 KB
testcase_39 AC 31 ms
5,376 KB
testcase_40 AC 2 ms
5,376 KB
testcase_41 AC 1 ms
5,376 KB
testcase_42 AC 1 ms
5,376 KB
権限があれば一括ダウンロードができます
コンパイルメッセージ
warning: unused variable: `cap`
  --> main.rs:61:10
   |
61 |     let (cap, cost) = flow.flow(n, n + 1, n as i64).unwrap_err();
   |          ^^^ help: if this is intentional, prefix it with an underscore: `_cap`
   |
   = note: `#[warn(unused_variables)]` on by default

warning: 1 warning emitted

ソースコード

diff #

#![allow(unused_imports)]
use std::cmp::*;
use std::collections::*;
use std::io::Write;
use std::ops::Bound::*;

#[allow(unused_macros)]
macro_rules! debug {
    ($($e:expr),*) => {
        #[cfg(debug_assertions)]
        $({
            let (e, mut err) = (stringify!($e), std::io::stderr());
            writeln!(err, "{} = {:?}", e, $e).unwrap()
        })*
    };
}

fn main() {
    let n = read::<usize>();
    let s = read::<String>();
    let v = read_vec::<i64>();

    let mut poses = vec![vec![]; 4];
    for (i, ch) in s.chars().enumerate() {
        match ch {
            'y' => poses[0].push(i),
            'u' => poses[1].push(i),
            'k' => poses[2].push(i),
            _ => poses[3].push(i),
        }
    }
    if poses.iter().any(|ref x| x.is_empty()) {
        println!("0");
        return;
    }

    let mut flow = Graph::new(n + 2);
    flow.add_edge(n, poses[0][0], n as i64, 0);

    let inf: i64 = 10_0000_0000;

    for ci in 0..3 {
        for &pos in &poses[ci] {
            let search = poses[ci + 1].upper_bound(&pos);
            if search < poses[ci + 1].len() {
                flow.add_edge(pos, poses[ci + 1][search], 1, inf - v[pos]);
            }
        }
    }

    for ci in 0..4 {
        for i in 0..poses[ci].len() - 1 {
            flow.add_edge(poses[ci][i], poses[ci][i + 1], n as i64, 0);
        }
    }

    for &pos in &poses[3] {
        flow.add_edge(pos, n + 1, 1, inf - v[pos]);
    }

    let (cap, cost) = flow.flow(n, n + 1, n as i64).unwrap_err();
    let ans = cost;
    println!("{}", ans);
}

pub trait BinarySearch<T> {
    fn upper_bound(&self, x: &T) -> usize;
}

impl<T: Ord> BinarySearch<T> for [T] {
    fn upper_bound(&self, x: &T) -> usize {
        let mut low = 0;
        let mut high = self.len();

        while low != high {
            let mid = (low + high) / 2;
            match self[mid].cmp(x) {
                Ordering::Less | Ordering::Equal => {
                    low = mid + 1;
                }
                Ordering::Greater => {
                    high = mid;
                }
            }
        }
        low
    }
}

fn read<T: std::str::FromStr>() -> T {
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).ok();
    s.trim().parse().ok().unwrap()
}

fn read_vec<T: std::str::FromStr>() -> Vec<T> {
    read::<String>()
        .split_whitespace()
        .map(|e| e.parse().ok().unwrap())
        .collect()
}

const INF: i64 = 1_000_000_000_000_000i64 + 1;

const GETA: i64 = 1_000_000_000;

struct Graph {
    size: usize,
    edge: Vec<(usize, usize, i64, i64)>,
}

impl Graph {
    fn new(size: usize) -> Self {
        Graph {
            size: size,
            edge: vec![],
        }
    }
    fn add_edge(&mut self, src: usize, dst: usize, capa: i64, cost: i64) {
        assert!(src < self.size && dst < self.size && src != dst);
        self.edge.push((src, dst, capa, cost));
    }
    fn flow(&self, src: usize, dst: usize, flow: i64) -> Result<i64, (i64, i64)> {
        if src == dst {
            return Ok(0);
        }
        let size = self.size;
        let edge = &self.edge;
        let mut deg = vec![0; size];
        for &(a, b, _, _) in edge.iter() {
            deg[a] += 1;
            deg[b] += 1;
        }
        let mut graph: Vec<_> = deg.into_iter().map(|d| Vec::with_capacity(d)).collect();
        for &(a, b, capa, cost) in edge.iter() {
            let x = graph[a].len();
            let y = graph[b].len();
            graph[a].push((b, capa, cost, y));
            graph[b].push((a, 0, -cost, x));
        }
        let mut ans = 0;
        let mut rem = flow;
        let mut dp = Vec::with_capacity(size);
        let mut pot = vec![0; size];
        let mut h = std::collections::BinaryHeap::new();
        while rem > 0 {
            dp.clear();
            dp.resize(size, (INF, src, 0)); // コスト、親、親からの番号
            dp[src] = (0, src, 0);
            h.push((0, src));
            while let Some((d, v)) = h.pop() {
                let d = -d;
                if d > dp[v].0 {
                    continue;
                }
                for (i, &(u, capa, cost, _)) in graph[v].iter().enumerate() {
                    if capa == 0 {
                        continue;
                    }
                    let c = d + cost - pot[u] + pot[v];
                    if c < dp[u].0 {
                        dp[u] = (c, v, i);
                        h.push((-c, u));
                    }
                }
            }
            if dp[dst].0 == INF {
                return Err((flow - rem, ans));
            }
            let mut sub = rem;
            let mut pos = dst;
            while pos != src {
                let (_, parent, k) = dp[pos];
                sub = sub.min(graph[parent][k].1);
                pos = parent;
            }
            rem -= sub;
            ans = ans.max(ans + GETA * 4 * sub - dp[dst].0 - pot[dst]);
            let mut pos = dst;
            while pos != src {
                let (_, parent, k) = dp[pos];
                let inv = graph[parent][k].3;
                graph[parent][k].1 -= sub;
                graph[pos][inv].1 += sub;
                pos = parent;
            }
            for i in 0..size {
                pot[i] -= pot[dst] - pot[i];
            }
        }
        Ok(ans)
    }
}
0