1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
use petgraph::{
prelude::*,
visit::{DfsPostOrder, IntoEdges, VisitMap},
};
pub fn dfs_next_filtered<N, VM, G>(
dfs: &mut DfsPostOrder<N, VM>,
graph: G,
mut edge_filter: impl FnMut(G::EdgeRef) -> bool,
) -> Option<N>
where
N: Copy + PartialEq,
VM: VisitMap<N>,
G: IntoEdges<NodeId = N>,
{
while let Some(&nx) = dfs.stack.last() {
if dfs.discovered.visit(nx) {
let neighbors = graph.edges(nx).filter_map(|edge| {
if edge_filter(edge) {
Some(edge.target())
} else {
None
}
});
for succ in neighbors {
if !dfs.discovered.is_visited(&succ) {
dfs.stack.push(succ);
}
}
} else {
dfs.stack.pop();
if dfs.finished.visit(nx) {
return Some(nx);
}
}
}
None
}