結果
問題 | No.957 植林 |
ユーザー | akakimidori |
提出日時 | 2020-02-13 22:56:39 |
言語 | Rust (1.77.0 + proconio) |
結果 |
AC
|
実行時間 | 336 ms / 2,000 ms |
コード長 | 5,051 bytes |
コンパイル時間 | 22,966 ms |
コンパイル使用メモリ | 399,636 KB |
実行使用メモリ | 13,176 KB |
最終ジャッジ日時 | 2024-10-06 06:40:07 |
合計ジャッジ時間 | 22,133 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge4 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 1 ms
6,820 KB |
testcase_01 | AC | 1 ms
6,820 KB |
testcase_02 | AC | 1 ms
6,820 KB |
testcase_03 | AC | 38 ms
10,176 KB |
testcase_04 | AC | 34 ms
9,532 KB |
testcase_05 | AC | 37 ms
10,208 KB |
testcase_06 | AC | 41 ms
10,860 KB |
testcase_07 | AC | 35 ms
9,588 KB |
testcase_08 | AC | 32 ms
10,280 KB |
testcase_09 | AC | 33 ms
10,168 KB |
testcase_10 | AC | 34 ms
10,768 KB |
testcase_11 | AC | 32 ms
10,284 KB |
testcase_12 | AC | 30 ms
10,132 KB |
testcase_13 | AC | 26 ms
9,360 KB |
testcase_14 | AC | 37 ms
11,160 KB |
testcase_15 | AC | 33 ms
10,068 KB |
testcase_16 | AC | 29 ms
9,532 KB |
testcase_17 | AC | 29 ms
9,640 KB |
testcase_18 | AC | 252 ms
10,080 KB |
testcase_19 | AC | 255 ms
10,440 KB |
testcase_20 | AC | 257 ms
10,696 KB |
testcase_21 | AC | 274 ms
10,840 KB |
testcase_22 | AC | 296 ms
10,968 KB |
testcase_23 | AC | 301 ms
13,156 KB |
testcase_24 | AC | 313 ms
11,660 KB |
testcase_25 | AC | 333 ms
11,812 KB |
testcase_26 | AC | 330 ms
11,808 KB |
testcase_27 | AC | 328 ms
11,812 KB |
testcase_28 | AC | 328 ms
12,868 KB |
testcase_29 | AC | 329 ms
11,940 KB |
testcase_30 | AC | 330 ms
13,036 KB |
testcase_31 | AC | 243 ms
10,216 KB |
testcase_32 | AC | 256 ms
10,436 KB |
testcase_33 | AC | 263 ms
10,696 KB |
testcase_34 | AC | 299 ms
12,336 KB |
testcase_35 | AC | 301 ms
10,972 KB |
testcase_36 | AC | 309 ms
11,236 KB |
testcase_37 | AC | 315 ms
11,536 KB |
testcase_38 | AC | 334 ms
11,816 KB |
testcase_39 | AC | 330 ms
11,940 KB |
testcase_40 | AC | 336 ms
11,816 KB |
testcase_41 | AC | 38 ms
11,432 KB |
testcase_42 | AC | 37 ms
11,564 KB |
testcase_43 | AC | 41 ms
12,096 KB |
testcase_44 | AC | 40 ms
13,176 KB |
testcase_45 | AC | 1 ms
6,816 KB |
testcase_46 | AC | 0 ms
6,816 KB |
testcase_47 | AC | 0 ms
6,816 KB |
ソースコード
// https://cp-algorithms.com/graph/mpm.html use std::cmp::*; type FlowType = i64; struct MPMGraph { size: usize, edge: Vec<(usize, usize, FlowType)>, } impl MPMGraph { pub fn new(size: usize) -> Self { MPMGraph { size: size, edge: vec![], } } fn add_edge(&mut self, src: usize, dst: usize, capa: FlowType) { assert!(src < self.size && dst < self.size); if src != dst { self.edge.push((src, dst, capa)); self.edge.push((dst, src, 0)); } } #[inline(never)] fn flow(&mut self, src: usize, dst: usize) -> FlowType { // 多重辺のマージ self.edge.sort(); self.edge.dedup_by(|a, b| { if a.0 == b.0 && a.1 == b.1 { b.2 += a.2; true } else { false } }); // 次数の計算 let mut deg = vec![0; self.size]; for e in self.edge.iter() { deg[e.0] += 1; } let mut graph = Vec::with_capacity(self.size); for deg in deg.into_iter() { graph.push(Vec::with_capacity(deg)); } // グラフの構築 let mut used = vec![false; self.edge.len()]; for (i, &(s, t, c)) in self.edge.iter().enumerate() { if used[i] { continue; } let x = graph[s].len(); let y = graph[t].len(); let k = self.edge.binary_search_by(|e| (e.0, e.1).cmp(&(t, s))).unwrap(); graph[s].push((t, c, y)); graph[t].push((s, self.edge[k].2, x)); used[i] = true; used[k] = true; } // フローが流れなくなるまでループ let mut it = vec![0; self.size]; let mut ans = 0; loop { // 到達可能性を確かめる let depth = MPMGraph::bfs(src, dst, &graph); // 到達不能 if depth[dst] >= self.size { break; } it.clear(); it.resize(self.size, 0); loop { let f = MPMGraph::dfs(dst, src, &mut graph, &mut it, 1_000_000_000_000_000_000i64, &depth); if f == 0 { break; } ans += f; } } ans } #[inline(never)] fn dfs(v: usize, src: usize, graph: &mut [Vec<(usize, FlowType, usize)>], it: &mut [usize], mut capa: FlowType, depth: &[usize]) -> FlowType { if v == src { return capa; } let mut sum = 0; for i in it[v]..graph[v].len() { let (u, _, inv) = graph[v][i]; if depth[u] < depth[v] && graph[u][inv].1 > 0 { let c = min(graph[u][inv].1, capa); let f = MPMGraph::dfs(u, src, graph, it, c, depth); sum += f; capa -= f; graph[v][i].1 += f; graph[u][inv].1 -= f; if capa == 0 { return sum; } } it[v] += 1; } sum } #[inline(never)] fn bfs(src: usize, dst: usize, graph: &[Vec<(usize, FlowType, usize)>]) -> Vec<usize> { let mut depth = vec![graph.len(); graph.len()]; depth[src] = 0; let mut q = std::collections::VecDeque::new(); q.push_back(src); 'outer: while let Some(v) = q.pop_front() { for &(u, c, _) in graph[v].iter() { if c > 0 && depth[u] > depth[v] + 1 { depth[u] = depth[v] + 1; if u == dst { break 'outer; } q.push_back(u); } } } depth } } fn run() { use std::io::Read; let mut s = String::new(); std::io::stdin().read_to_string(&mut s).unwrap(); let mut it = s.trim().split_whitespace(); let h: usize = it.next().unwrap().parse().unwrap(); let w: usize = it.next().unwrap().parse().unwrap(); let a: Vec<Vec<i64>> = (0..h).map(|_| (0..w).map(|_| it.next().unwrap().parse().unwrap()).collect()).collect(); let r: Vec<i64> = (0..h).map(|_| it.next().unwrap().parse().unwrap()).collect(); let c: Vec<i64> = (0..w).map(|_| it.next().unwrap().parse().unwrap()).collect(); let mut graph = MPMGraph::new(h + w + 2); let src = h + w; let dst = src + 1; for (i, a) in a.iter().enumerate() { let mut local = 0; for (j, a) in a.iter().enumerate() { graph.add_edge(h + j, i, *a); local += *a; } graph.add_edge(i, dst, local); } let mut sum = 0; for (i, r) in r.iter().enumerate() { sum += *r; graph.add_edge(src, i, *r); } for (i, c) in c.iter().enumerate() { sum += *c; graph.add_edge(src, i + h, *c); } let ans = sum - graph.flow(src, dst); println!("{}", ans); } fn main() { run(); }