algorithms_edu/algo/graph/tree/
center.rs1use crate::algo::graph::UnweightedAdjacencyList;
10
11#[derive(Debug, Eq, PartialEq)]
13pub enum Center {
14 One(usize),
15 Two(usize, usize),
16}
17
18impl UnweightedAdjacencyList {
19 pub fn center(&self) -> Center {
23 let n = self.node_count();
24 let mut degrees = vec![0; n];
27 let mut leaves = Vec::new();
28 self.nodes().for_each(|(i, neighbours)| {
31 let degree = neighbours.len();
32 if degree <= 1 {
36 leaves.push(i);
37 }
38 degrees[i] = degree;
39 });
40 let mut processed_leaves = leaves.len();
41 while processed_leaves < n {
46 let mut new_leaves = Vec::new();
47 for &leaf in &leaves {
48 for &neighbour in &self[leaf] {
49 degrees[neighbour] = degrees[neighbour].saturating_sub(1);
50 if degrees[neighbour] == 1 {
51 new_leaves.push(neighbour);
52 }
53 }
54 }
55 processed_leaves += new_leaves.len();
56 leaves = new_leaves;
57 }
58 match leaves.len() {
59 1 => Center::One(leaves[0]),
60 2 => Center::Two(leaves[0], leaves[1]),
61 _ => unreachable!(),
62 }
63 }
64}
65
66#[cfg(test)]
67mod tests {
68 use super::*;
69
70 #[test]
71 fn test_tree_center() {
72 let graph = UnweightedAdjacencyList::with_size(1);
73 assert_eq!(graph.center(), Center::One(0));
74
75 let mut graph = UnweightedAdjacencyList::with_size(2);
76 graph.add_undirected_edge(0, 1);
77 assert_eq!(graph.center(), Center::Two(0, 1));
78
79 let mut graph = UnweightedAdjacencyList::with_size(3);
80 graph.add_undirected_edge(0, 1);
81 graph.add_undirected_edge(1, 2);
82 assert_eq!(graph.center(), Center::One(1));
83
84 let mut graph = UnweightedAdjacencyList::with_size(9);
85 graph.add_undirected_edge(0, 1);
86 graph.add_undirected_edge(2, 1);
87 graph.add_undirected_edge(2, 3);
88 graph.add_undirected_edge(3, 4);
89 graph.add_undirected_edge(5, 3);
90 graph.add_undirected_edge(2, 6);
91 graph.add_undirected_edge(6, 7);
92 graph.add_undirected_edge(6, 8);
93 assert_eq!(graph.center(), Center::One(2));
94 }
95}