1use super::union_find::UnionFind;
2use super::heap;
3use std::collections::{HashSet, HashMap};
4
5pub fn slashburn(edges: &[(usize, usize)], n_nodes: usize, k: usize) -> Vec<usize>{
6
7 let mut remain_edges : Vec<(usize, usize)> = edges.iter().copied().collect();
8 let mut remain_nodes : HashSet<usize> = (0..n_nodes).collect();
9 let mut new_node_order = vec![0usize; n_nodes];
10 let mut cur_hubs = 0;
11 let mut cur_spokes = n_nodes;
12
13 let mut degrees = vec![0; n_nodes].into_boxed_slice();
14
15 let mut uf = UnionFind::new(n_nodes);
16
17 for (u, v) in edges{
18 degrees[*u] += 1;
19 degrees[*v] += 1;
20 }
21
22 loop{
23 eprintln!("remain edges: {}, remain_nodes: {}", remain_edges.len(), remain_nodes.len());
24
25 let hubs_remain = topk(k, &remain_nodes, °rees);
26 let hubset_remain : HashSet<usize> = hubs_remain.iter().copied().collect();
27
28 remain_nodes.retain(|u| !hubset_remain.contains(u));
29
30 remain_edges.retain(|(u, v)| {
31 if remain_nodes.contains(u) && remain_nodes.contains(v) {
32 return true;
33 }
34 else{
35 degrees[*u] -= 1;
36 degrees[*v] -= 1;
37 return false;
38 }
39 });
40
41 new_node_order[cur_hubs..cur_hubs + hubs_remain.len()].clone_from_slice(&hubs_remain);
42 cur_hubs += hubs_remain.len();
43 if remain_nodes.is_empty() {
46 break;
47 }
48
49 let spokes_remain = find_and_remove_spokes(&remain_edges, &mut remain_nodes, &mut uf);
50
51
52 new_node_order[cur_spokes-spokes_remain.len()..cur_spokes].clone_from_slice(&spokes_remain);
53 cur_spokes -= spokes_remain.len();
54 if remain_nodes.is_empty() {
57 break;
58 }
59 }
60
61 assert_eq!(cur_spokes, cur_hubs);
62
63 return new_node_order;
64
65}
66
67fn find_and_remove_spokes(edges: &[(usize, usize)], nodes: &mut HashSet<usize>, uf: &mut UnionFind) -> Vec<usize>{
68
69 uf.reset(nodes.iter());
70
71 for (u, v) in edges.iter() {
72 uf.union(*u, *v);
73 }
74
75 let cc : Vec<usize> = nodes.iter().map(|u| uf.find(*u)).collect();
76
77 let mut cc_sizes : HashMap<usize, usize> = HashMap::new();
78 for c in &cc{
79 *cc_sizes.entry(*c).or_insert(0) += 1;
80 }
81
82 let (gccid, gcccnt) = cc_sizes.into_iter().max_by(|(_, x), (_, y)| x.cmp(y)).expect("What the hell?");
83
84 let mut spokes = Vec::with_capacity(nodes.len() - gcccnt);
85
86
87 nodes.retain(|u| {
88 if gccid == uf.find(*u) {
89 true
90 }
91 else{
92 spokes.push(*u);
93 false
94 }
95 });
96
97 spokes.sort_by(|a,b| uf.find(*a).cmp(&uf.find(*b)));
98
99 return spokes;
100}
101
102fn topk(k: usize, keys: &HashSet<usize>, values: &[usize]) -> Vec<usize> {
103
104 let k = if k < keys.len() { k } else { keys.len() };
105
106 let mut key_iter = keys.iter();
107
108 let mut heap : Vec<usize> = vec![0;k];
109 for i in heap.iter_mut(){
110 *i = *key_iter.next().unwrap();
111 }
112
113 heap::heapify_indices(&mut heap, &values);
114
115 for x in key_iter{
116 heap::heap_push_indices(*x, &mut heap, &values);
117 }
118
119 heap::sort_heap_indices(&mut heap, &values);
120
121 return heap;
122}