Submission #41691054


Source Code Expand

Copy
use dsu::Dsu;
use proconio::{input, marker::Usize1};
fn main() {
input! {
n: usize,
m: usize,
xyc: [(i64, i64, Usize1); n],
capital_xyc: [(i64, i64, Usize1); m],
}
let mut ans = std::f64::MAX;
for bits in 0_usize..1 << m {
let n = n + bits.count_ones() as usize;
let vertices = xyc
.iter()
.copied()
.chain(
(0..m)
.filter(|i| ((bits >> i) & 1) == 1)
.map(|i| capital_xyc[i]),
 
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
use dsu::Dsu;
use proconio::{input, marker::Usize1};

fn main() {
    input! {
        n: usize,
        m: usize,
        xyc: [(i64, i64, Usize1); n],
        capital_xyc: [(i64, i64, Usize1); m],
    }

    let mut ans = std::f64::MAX;
    for bits in 0_usize..1 << m {
        let n = n + bits.count_ones() as usize;
        let vertices = xyc
            .iter()
            .copied()
            .chain(
                (0..m)
                    .filter(|i| ((bits >> i) & 1) == 1)
                    .map(|i| capital_xyc[i]),
            )
            .collect::<Vec<(i64, i64, usize)>>();

        let mut edges = vec![];
        for (i, (x_i, y_i, c_i)) in vertices.iter().copied().enumerate() {
            for (j, (x_j, y_j, c_j)) in vertices.iter().copied().enumerate() {
                if i == j {
                    continue;
                }
                let cost = (((x_i - x_j).pow(2) + (y_i - y_j).pow(2)) as f64).sqrt();
                edges.push((i, j, cost * if c_i == c_j { 1_f64 } else { 10_f64 }));
            }
        }

        edges.sort_by(|(_, _, a), (_, _, b)| a.partial_cmp(b).unwrap());

        let mut sum = 0_f64;
        let mut dsu = Dsu::new(n);
        for (u, v, c) in edges {
            if dsu.same(u, v) {
                continue;
            }
            dsu.merge(u, v);
            sum += c;
        }

        ans = ans.min(sum);
    }
    println!("{}", ans);
}

//https://github.com/rust-lang-ja/ac-library-rs

pub mod dsu {
    /// Implement (union by size) + (path compression)
    /// Reference:
    /// Zvi Galil and Giuseppe F. Italiano,
    /// Data structures and algorithms for disjoint set union problems
    pub struct Dsu {
        n: usize,
        // root node: -1 * component size
        // otherwise: parent
        parent_or_size: Vec<i32>,
    }

    impl Dsu {
        // 0 <= size <= 10^8 is constrained.
        pub fn new(size: usize) -> Self {
            Self {
                n: size,
                parent_or_size: vec![-1; size],
            }
        }
        pub fn merge(&mut self, a: usize, b: usize) -> usize {
            assert!(a < self.n);
            assert!(b < self.n);
            let (mut x, mut y) = (self.leader(a), self.leader(b));
            if x == y {
                return x;
            }
            if -self.parent_or_size[x] < -self.parent_or_size[y] {
                std::mem::swap(&mut x, &mut y);
            }
            self.parent_or_size[x] += self.parent_or_size[y];
            self.parent_or_size[y] = x as i32;
            x
        }

        pub fn same(&mut self, a: usize, b: usize) -> bool {
            assert!(a < self.n);
            assert!(b < self.n);
            self.leader(a) == self.leader(b)
        }
        pub fn leader(&mut self, a: usize) -> usize {
            assert!(a < self.n);
            if self.parent_or_size[a] < 0 {
                return a;
            }
            self.parent_or_size[a] = self.leader(self.parent_or_size[a] as usize) as i32;
            self.parent_or_size[a] as usize
        }
        pub fn size(&mut self, a: usize) -> usize {
            assert!(a < self.n);
            let x = self.leader(a);
            -self.parent_or_size[x] as usize
        }
        pub fn groups(&mut self) -> Vec<Vec<usize>> {
            let mut leader_buf = vec![0; self.n];
            let mut group_size = vec![0; self.n];
            for i in 0..self.n {
                leader_buf[i] = self.leader(i);
                group_size[leader_buf[i]] += 1;
            }
            let mut result = vec![Vec::new(); self.n];
            for i in 0..self.n {
                result[i].reserve(group_size[i]);
            }
            for i in 0..self.n {
                result[leader_buf[i]].push(i);
            }
            result
                .into_iter()
                .filter(|x| !x.is_empty())
                .collect::<Vec<Vec<usize>>>()
        }
    }

    #[cfg(test)]
    mod tests {
        use super::*;

        #[test]
        fn dsu_works() {
            let mut d = Dsu::new(4);
            d.merge(0, 1);
            assert_eq!(d.same(0, 1), true);
            d.merge(1, 2);
            assert_eq!(d.same(0, 2), true);
            assert_eq!(d.size(0), 3);
            assert_eq!(d.same(0, 3), false);
            assert_eq!(d.groups(), vec![vec![0, 1, 2], vec![3]]);
        }
    }
}

Submission Info

Submission Time
Task L - Gradation
User bouzuya
Language Rust (1.42.0)
Score 6
Code Size 4381 Byte
Status AC
Exec Time 12 ms
Memory 2288 KB

Judge Result

Set Name Sample All
Score / Max Score 0 / 0 6 / 6
Status
AC × 2
AC × 31
Set Name Test Cases
Sample example_01.txt, example_02.txt
All example_01.txt, example_02.txt, subtask_01_01.txt, subtask_01_02.txt, subtask_01_03.txt, subtask_01_04.txt, subtask_01_05.txt, subtask_01_06.txt, subtask_01_07.txt, subtask_01_08.txt, subtask_01_09.txt, subtask_01_10.txt, subtask_01_11.txt, subtask_01_12.txt, subtask_01_13.txt, subtask_01_14.txt, subtask_01_15.txt, subtask_01_16.txt, subtask_01_17.txt, subtask_01_18.txt, subtask_01_19.txt, subtask_01_20.txt, subtask_01_21.txt, subtask_01_22.txt, subtask_01_23.txt, subtask_01_24.txt, subtask_01_25.txt, subtask_01_26.txt, subtask_01_27.txt, subtask_01_28.txt, subtask_01_29.txt
Case Name Status Exec Time Memory
example_01.txt AC 8 ms 2128 KB
example_02.txt AC 2 ms 2120 KB
subtask_01_01.txt AC 2 ms 2116 KB
subtask_01_02.txt AC 2 ms 2148 KB
subtask_01_03.txt AC 2 ms 2236 KB
subtask_01_04.txt AC 2 ms 2244 KB
subtask_01_05.txt AC 2 ms 2144 KB
subtask_01_06.txt AC 2 ms 2104 KB
subtask_01_07.txt AC 7 ms 2156 KB
subtask_01_08.txt AC 6 ms 2280 KB
subtask_01_09.txt AC 10 ms 2116 KB
subtask_01_10.txt AC 2 ms 2240 KB
subtask_01_11.txt AC 8 ms 2076 KB
subtask_01_12.txt AC 8 ms 2112 KB
subtask_01_13.txt AC 2 ms 2124 KB
subtask_01_14.txt AC 7 ms 2180 KB
subtask_01_15.txt AC 9 ms 2096 KB
subtask_01_16.txt AC 2 ms 2108 KB
subtask_01_17.txt AC 5 ms 2112 KB
subtask_01_18.txt AC 6 ms 2152 KB
subtask_01_19.txt AC 1 ms 2032 KB
subtask_01_20.txt AC 12 ms 2224 KB
subtask_01_21.txt AC 8 ms 2288 KB
subtask_01_22.txt AC 2 ms 2132 KB
subtask_01_23.txt AC 6 ms 2144 KB
subtask_01_24.txt AC 6 ms 2208 KB
subtask_01_25.txt AC 9 ms 2216 KB
subtask_01_26.txt AC 6 ms 2208 KB
subtask_01_27.txt AC 6 ms 2088 KB
subtask_01_28.txt AC 6 ms 2152 KB
subtask_01_29.txt AC 2 ms 2056 KB


2025-04-05 (Sat)
08:56:30 +00:00