use crate::graph::{Edge, Graph};
pub fn longest_path(graph: &mut Graph) {
let mut visited: std::collections::HashMap<String, bool> = std::collections::HashMap::new();
fn dfs(
graph: &mut Graph,
v: &str,
visited: &mut std::collections::HashMap<String, bool>,
) -> i32 {
if visited.contains_key(v) {
return graph.node(v).rank.unwrap_or(0);
}
visited.insert(v.to_string(), true);
let out_edges: Vec<Edge> = graph.out_edges(v).unwrap_or_default();
let mut min_rank = i32::MAX;
for e in out_edges {
let w_rank = dfs(graph, &e.w.clone(), visited);
let minlen = graph.edge(&e).map_or(1, |l| l.minlen.unwrap_or(1));
let candidate = w_rank - minlen;
if candidate < min_rank {
min_rank = candidate;
}
}
let rank = if min_rank == i32::MAX { 0 } else { min_rank };
graph.node_mut(v).rank = Some(rank);
rank
}
let sources: Vec<String> = graph.sources();
for v in sources {
dfs(graph, &v, &mut visited);
}
}
pub fn slack(graph: &Graph, edge: &Edge) -> i32 {
let rank_w = graph.node(&edge.w).rank.unwrap_or(0);
let rank_v = graph.node(&edge.v).rank.unwrap_or(0);
let minlen = graph.edge(edge).map_or(1, |l| l.minlen.unwrap_or(1));
rank_w - rank_v - minlen
}