pub fn is_forest(
graph: &Graph,
mode: DijkstraMode,
) -> IgraphResult<Option<Vec<VertexId>>>Expand description
Returns Some(roots) iff graph is a forest under mode,
otherwise None. The null graph is a forest with empty roots.
For undirected graphs the mode argument is ignored. For directed graphs:
DijkstraMode::Out: roots are the vertices with in-degree0(one per tree component).DijkstraMode::In: roots are the vertices with out-degree0(one per tree component).DijkstraMode::All: orientation ignored; the canonical root of each component is the lowest-indexed unvisited vertex reached during a left-to-right scan.
Counterpart of igraph_is_forest(_, _, _, mode) from
references/igraph/src/properties/trees.c:520.
§Examples
use rust_igraph::{Graph, is_forest, DijkstraMode};
// Two disjoint undirected edges: 0-1 and 2-3 form a forest.
let mut g = Graph::with_vertices(4);
g.add_edges(vec![(0u32, 1u32), (2, 3)]).unwrap();
let roots = is_forest(&g, DijkstraMode::All).unwrap().unwrap();
assert_eq!(roots, vec![0, 2]);
// Triangle 0-1-2-0 has a cycle ⇒ not a forest.
let mut g = Graph::with_vertices(3);
g.add_edges(vec![(0u32, 1u32), (1, 2), (2, 0)]).unwrap();
assert!(is_forest(&g, DijkstraMode::All).unwrap().is_none());
// Two disjoint out-arborescences 0→1 and 2→3.
let mut g = Graph::new(4, true).unwrap();
g.add_edges(vec![(0u32, 1u32), (2, 3)]).unwrap();
let roots = is_forest(&g, DijkstraMode::Out).unwrap().unwrap();
assert_eq!(roots, vec![0, 2]);
// 0→2←1: not an out-forest (in-degree 2 at vertex 2),
// but is an undirected forest (treated as 0-2-1 path).
let mut g = Graph::new(3, true).unwrap();
g.add_edges(vec![(0u32, 2u32), (1, 2)]).unwrap();
assert!(is_forest(&g, DijkstraMode::Out).unwrap().is_none());
assert!(is_forest(&g, DijkstraMode::All).unwrap().is_some());