use polygon_unionfind::UnionFind;
use crate::Vector2;
pub fn inflated_seg(x1: i64, y1: i64, x2: i64, y2: i64, half_width: u64) -> [Vector2<i64>; 4] {
let dx = x2 - x1;
let dy = y2 - y1;
let approx_len = std::cmp::max(dx.abs(), dy.abs()) + 3 * std::cmp::min(dx.abs(), dy.abs()) / 8;
let px = -dy * (half_width as i64) / approx_len;
let py = dx * (half_width as i64) / approx_len;
[
Vector2::new(x1 + px, y1 + py),
Vector2::new(x2 + px, y2 + py),
Vector2::new(x2 - px, y2 - py),
Vector2::new(x1 - px, y1 - py),
]
}
pub fn kruskal_mst<W: Copy + Ord>(
vertex_count: usize,
edges: &[(W, [usize; 2])],
) -> Vec<[usize; 2]> {
let mut sorted_edges = edges.to_vec();
sorted_edges.sort_by_key(|(w, _)| *w);
let mut unionfind: UnionFind = UnionFind::with_len(vertex_count);
let mut min_spanning_tree = Vec::new();
for (_, uv) in sorted_edges {
if unionfind.union(uv[0], uv[1]) {
min_spanning_tree.push(uv);
}
}
min_spanning_tree
}
#[cfg(test)]
mod tests {
use super::kruskal_mst;
#[test]
fn kruskal_mst_on_path_graph() {
let edges = [(1, [0, 1]), (2, [1, 2]), (3, [2, 3])];
let mst = kruskal_mst(4, &edges);
assert_eq!(mst.len(), 3);
assert_eq!(mst, [[0, 1], [1, 2], [2, 3]]);
}
#[test]
fn kruskal_mst_on_triangle() {
let edges = [(1, [0, 1]), (2, [1, 2]), (3, [0, 2])];
let mst = kruskal_mst(3, &edges);
assert_eq!(mst.len(), 2);
assert!(mst.contains(&[0, 1]));
assert!(mst.contains(&[1, 2]));
}
}