2023-10-20 子どもが嘔吐して 1 回休み / PAST#6 L
子どもが嘔吐して 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