competitive/algorithm/
chromatic_number.rs1use super::{MInt, MIntBase, One, Zero, binary_search};
2
3#[derive(Debug, Clone)]
4pub struct IndependentSubSet<M: MIntBase> {
5 pub n: usize,
6 pub ind: Vec<MInt<M>>,
7}
8impl<M: MIntBase> IndependentSubSet<M> {
9 pub fn from_adj_graph(g: &[usize]) -> Self {
10 let n = g.len();
11 let mut ind = Vec::with_capacity(1 << n);
12 ind.push(MInt::one());
13 for s in 1usize..1 << n {
14 let v = s.trailing_zeros() as usize;
15 ind.push(ind[s - (1 << v)] + ind[s & !(g[v] | (1 << v))]);
16 }
17 Self { n, ind }
18 }
19 pub fn k_colorable(&self, k: usize) -> bool {
20 !self
21 .ind
22 .iter()
23 .map(|d| d.pow(k))
24 .enumerate()
25 .map(|(s, d)| if s.count_ones() % 2 == 0 { d } else { -d })
26 .sum::<MInt<M>>()
27 .is_zero()
28 }
29 pub fn chromatic_number(&self) -> usize {
31 binary_search(|&k| self.k_colorable(k), self.n, 0)
32 }
33}