#[derive(Debug)] struct Vertex { name: u16, edges: Vec, } #[derive(Debug)] pub struct Graph { index: Vec, vertices: Vec, stack: Vec, } impl Graph { pub fn new(g: &crate::Graph) -> Self { let mut vertices: Vec<_> = (0..g.num_vertices()) .map(|i| Vertex { name: i, edges: Vec::new(), }) .collect(); for (start, s) in g.edge_list.iter().enumerate() { vertices[start].edges.extend_from_slice(s); } Self { index: (0..g.num_vertices()).collect(), vertices, stack: Vec::new(), } } fn is_empty(&self) -> bool { self.vertices.is_empty() } fn remove_vertex(&mut self, v: u16) -> &Vertex { let i = self.index[v as usize]; // dbg!(&self.index, v, i); let vertex = self.vertices.swap_remove(i as usize); assert_eq!(vertex.name, v); if (i as usize) < self.vertices.len() { self.index[self.vertices[i as usize].name as usize] = i; } for &e in &vertex.edges { let i = self.index[e as usize]; let p = self.vertices[i as usize] .edges .iter() .position(|&o| o == v) .unwrap(); self.vertices[i as usize].edges.swap_remove(p); } // dbg!(&self.index); self.stack.push(vertex); self.stack.last().unwrap() } fn reinsert_vertices(&mut self, n: usize) -> impl Iterator { for _ in 0..n { let v = self.stack.pop().unwrap(); for &e in &v.edges { let i = self.index[e as usize]; self.vertices[i as usize].edges.push(v.name); } self.index[v.name as usize] = self.vertices.len() as u16; self.vertices.push(v); } self.vertices[(self.vertices.len() - n)..].iter() } fn get_vertex_with_degree_greater(&self, min_degree: u16) -> Option { self.vertices .iter() .find(|&v| v.edges.len() >= min_degree as usize) .map(|v| v.name) } fn get_vertex_with_degree(&self, degree: u16) -> Option { self.vertices .iter() .find(|&v| v.edges.len() == degree as usize) .map(|v| v.name) } fn get_edges(&self, v: u16) -> impl Iterator + '_ { let i = self.index[v as usize]; self.vertices[i as usize].edges.iter().copied() } fn get_edge(&self, v: u16) -> Option { self.get_edges(v).next() } fn get_degree(&self, v: u16) -> u16 { let i = self.index[v as usize]; self.vertices[i as usize].edges.len() as u16 } } pub fn binary_vertex(graph: &mut Graph, k: u16) -> Option> { let vertex = match graph.get_vertex_with_degree_greater(2) { Some(vertex) => vertex, None => { return { let mut c = 0; while let Some(vertex) = graph.get_vertex_with_degree_greater(1) { graph.remove_vertex(vertex); c += 1; } if c <= k { Some( graph .reinsert_vertices(c as usize) .map(|v| v.name) .collect(), ) } else { let _ = graph.reinsert_vertices(c as usize); None } } } }; if k == 0 { return None; } graph.remove_vertex(vertex); match binary_vertex(graph, k - 1) { Some(mut s) => { s.push(vertex); Some(s) } None => { let _ = graph.reinsert_vertices(1); let num_neighbors = graph.get_edges(vertex).count(); if num_neighbors <= k as usize { let mut c = 0; while let Some(e) = graph.get_edge(vertex) { graph.remove_vertex(e); c += 1; } let mut r = binary_vertex(graph, k - c); if let Some(r) = &mut r { r.extend(graph.reinsert_vertices(c as usize).map(|v| v.name)); } else { let _ = graph.reinsert_vertices(c as usize); } r } else { None } } } } pub fn reduction(graph: &mut Graph, k: u16) -> Option> { if let Some(vertex) = graph.get_vertex_with_degree(0) { graph.remove_vertex(vertex); let r = reduction(graph, k); let _ = graph.reinsert_vertices(1); r } else if k == 0 { if graph.is_empty() { Some(Vec::new()) } else { None } } else if let Some(vertex) = graph.get_vertex_with_degree(1) { let neighbor = graph.get_edge(vertex).unwrap(); graph.remove_vertex(neighbor); let mut r = reduction(graph, k - 1); let i = graph.reinsert_vertices(1); if let Some(r) = &mut r { r.extend(i.map(|v| v.name)); } r } else if let Some(vertex) = graph.get_vertex_with_degree_greater(2) { graph.remove_vertex(vertex); match reduction(graph, k - 1) { Some(mut s) => { let i = graph.reinsert_vertices(1); s.extend(i.map(|v| v.name)); Some(s) } None => { let _ = graph.reinsert_vertices(1); let num_neighbors = graph.get_edges(vertex).count(); if num_neighbors <= k as usize { let mut c = 0; while let Some(e) = graph.get_edge(vertex) { graph.remove_vertex(e); c += 1; } let mut r = reduction(graph, k - c); let i = graph.reinsert_vertices(c as usize); if let Some(r) = &mut r { r.extend(i.map(|v| v.name)); } r } else { None } } } } else { unreachable!() } } pub fn reduction2(graph: &mut Graph, k: u16) -> Option> { if let Some(vertex) = graph.get_vertex_with_degree(0) { graph.remove_vertex(vertex); let r = reduction2(graph, k); let _ = graph.reinsert_vertices(1); r } else if graph.is_empty() { Some(Vec::new()) } else if k == 0 { if graph.is_empty() { Some(Vec::new()) } else { None } } else if let Some(vertex) = graph.get_vertex_with_degree(1) { let neighbor = graph.get_edge(vertex).unwrap(); if k < 1 { return None; } graph.remove_vertex(neighbor); let mut r = reduction2(graph, k - 1); let i = graph.reinsert_vertices(1); if let Some(r) = &mut r { r.extend(i.map(|v| v.name)); } r } else if let Some(vertex) = graph.get_vertex_with_degree(2) { let (a, b) = { let mut i = graph.get_edges(vertex); (i.next().unwrap(), i.next().unwrap()) }; if graph.get_edges(a).any(|n| n == b) { if k < 2 { return None; } graph.remove_vertex(a); graph.remove_vertex(b); let mut r = reduction2(graph, k - 2); let i = graph.reinsert_vertices(2); if let Some(r) = &mut r { r.extend(i.map(|v| v.name)); } r } else if graph.get_degree(a) == 2 && graph.get_degree(b) == 2 && graph.get_edges(a).find(|&v| v != vertex).unwrap() == graph.get_edges(b).find(|&v| v != vertex).unwrap() { if k < 2 { return None; } let w = graph.get_edges(a).find(|&v| v != vertex).unwrap(); graph.remove_vertex(vertex); graph.remove_vertex(w); let mut r = reduction2(graph, k - 2); let i = graph.reinsert_vertices(2); if let Some(r) = &mut r { r.extend(i.map(|v| v.name)); } r } else { if k < 2 { return None; } graph.remove_vertex(a); graph.remove_vertex(b); match reduction2(graph, k - 2) { Some(mut s) => { let i = graph.reinsert_vertices(2); s.extend(i.map(|v| v.name)); Some(s) } None => { let _ = graph.reinsert_vertices(2); let mut c = 0; while let Some(e) = graph.get_edge(a) { graph.remove_vertex(e); c += 1; } while let Some(e) = graph.get_edge(b) { graph.remove_vertex(e); c += 1; } if c <= k { let mut r = reduction2(graph, k - c); let i = graph.reinsert_vertices(c as usize); if let Some(r) = &mut r { r.extend(i.map(|v| v.name)); } r } else { let _ = graph.reinsert_vertices(c as usize); None } } } } } else if let Some(vertex) = graph.get_vertex_with_degree_greater(3) { if k < 1 { return None; } graph.remove_vertex(vertex); match reduction2(graph, k - 1) { Some(mut s) => { let i = graph.reinsert_vertices(1); s.extend(i.map(|v| v.name)); Some(s) } None => { let _ = graph.reinsert_vertices(1); let num_neighbors = graph.get_edges(vertex).count(); if num_neighbors <= k as usize { let mut c = 0; while let Some(e) = graph.get_edge(vertex) { graph.remove_vertex(e); c += 1; } let mut r = reduction2(graph, k - c); let i = graph.reinsert_vertices(c as usize); if let Some(r) = &mut r { r.extend(i.map(|v| v.name)); } r } else { None } } } } else { unreachable!("{k}") } }