use crate::flow::{MaxFlowError, MaxFlowSolver, OriginalGraphView};
use crate::tree::{GomoryHuTree, TreeEdge};
#[derive(Debug, thiserror::Error)]
pub enum GomoryHuError {
#[error("Max-flow computation failed: {0}")]
MaxFlowComputationError(#[from] MaxFlowError),
#[error("Invalid graph structure: {0}")]
InvalidGraph(String),
#[error("Vertex {0} not found in graph (pre-computation check)")]
VertexNotFoundPreCheck(usize),
}
pub fn gusfield_tree<G, S>(graph: &G, solver: &S) -> Result<GomoryHuTree, GomoryHuError>
where
G: OriginalGraphView,
S: MaxFlowSolver<G, Flow = f64>,
{
let n = graph.vertex_count();
if n == 0 {
return Ok(GomoryHuTree::new(Vec::new(), 0));
}
if n == 1 {
return Ok(GomoryHuTree::new(Vec::new(), 1));
}
let mut parent = vec![0; n];
let mut tree_edges = Vec::with_capacity(n - 1);
for i in 1..n {
let (flow_value, min_cut) = solver.max_flow_min_cut(graph, i, parent[i])?;
tree_edges.push(TreeEdge::new(i, parent[i], flow_value));
for j in (i + 1)..n {
if parent[j] == parent[i] && min_cut.same_side(j, i) {
parent[j] = i;
}
}
}
Ok(GomoryHuTree::new(tree_edges, n))
}