子どもが嘔吐して 1 回休み。
長袖シャツをすべて捨てた。もうすこしシンプルにしたい。
『初めての GraphQL 』を読んだ。初めてではない。 ISUCON 本は?
- 都市計画 (第六回 アルゴリズム実技検定:L問題)
https://atcoder.jp/contests/past202104-open/tasks/past202104_l
- 提出: https://atcoder.jp/contests/past202104-open/submissions/46766178
- 使用するタワーの組み合わせを bit 全探索してそれぞれの最小全域木を求めれば良い
use dsu::*; use proconio::input; fn dist((px_i, py_i): (i64, i64), (px_j, py_j): (i64, i64)) -> f64 { (((px_i - px_j).pow(2) + (py_i - py_j).pow(2)) as f64).sqrt() } fn kruskal(n: usize, e: &mut [(usize, usize, f64)]) -> f64 { e.sort_by(|(_, _, w1), (_, _, w2)| w1.partial_cmp(w2).unwrap()); let mut dsu = Dsu::new(n); let mut sum = 0_f64; for (u_i, v_i, w_i) in e.iter().copied() { if !dsu.same(u_i, v_i) { dsu.merge(u_i, v_i); sum += w_i; } } sum } fn main() { input! { n: usize, m: usize, p: [(i64, i64); n], cr: [(i64, i64, i64); m], } let mut edges = vec![vec![]; n]; for (i, p_i) in p.iter().copied().enumerate() { for (j, p_j) in p.iter().copied().enumerate() { if i == j { continue; } edges[i].push((j, dist(p_i, p_j))); } } let mut min = 1e18; for bits in 0..1 << m { let cr = cr .iter() .copied() .enumerate() .filter(|(i, _)| ((bits >> i) & 1) == 1) .map(|(_, (x, y, r))| (x, y, r)) .collect::<Vec<_>>(); let m = cr.len(); let edges = { let mut e = vec![vec![]; n + m]; for (i, edges_i) in edges.iter().enumerate() { e[i] = edges_i.clone(); } for (i, p_i) in p.iter().copied().enumerate() { for (j, (cx_j, cy_j, r_j)) in cr.iter().copied().enumerate() { let d = (dist(p_i, (cx_j, cy_j)) - r_j as f64).abs(); e[i].push((n + j, d)); e[n + j].push((i, d)); } } for (i, (cx_i, cy_i, r_i)) in cr.iter().copied().enumerate() { for (j, (cx_j, cy_j, r_j)) in cr.iter().copied().enumerate() { if i == j { continue; } let d = (((cx_i - cx_j).pow(2) + (cy_i - cy_j).pow(2)) as f64).sqrt(); let r1 = (r_i + r_j) as f64; let r2 = (r_i - r_j).abs() as f64; let d = if r1 <= d { d - (r_i + r_j) as f64 } else if r2 < d { 0.0 } else { r2 - d }; e[n + i].push((n + j, d)); } } e }; let mut edges = { let mut e = vec![]; for (i, jd) in edges.into_iter().enumerate() { for (j, d) in jd { e.push((i, j, d)); } } e }; let min_cost = kruskal(n + m, &mut edges); if min_cost < min { min = min_cost; } } println!("{}", min); } // dsu
今日のコミット。
- kireta 1 commit
- rust-atcoder 1 commit