pub fn st_mincut(
graph: &Graph,
source: VertexId,
target: VertexId,
capacity: Option<&[f64]>,
) -> IgraphResult<StMincut>Expand description
Full s-t minimum-cut: scalar value, the cut edge list, and the source-side / sink-side vertex partitions.
Counterpart of igraph_st_mincut in
references/igraph/src/flow/flow.c:1140. The C entry is a
47-line wrapper around igraph_maxflow that requests the optional
cut, partition, and partition2 outputs alongside the flow
value. Our implementation:
- Calls the crate-private
max_flow_with_residualbackend (the shared Dinic entry point that also powersmax_flow_value) to obtain both the flow value and the final residual network. - Runs one BFS from
sourcein the residual graph (following only arcs with strictly positive residual capacity). The set of reachable vertices is precisely the source-sideSof a minimums-tcut (max-flow / min-cut duality, Ford-Fulkerson 1956). The complement ispartition2. - Walks the original edge list once: an original edge
(u, v)is in the cut iff it crosses the partition boundary — for directed input the cut edge pointsS → V \ S; for undirected input, either endpoint side suffices.
§Arguments
graph— input graph (directed or undirected).source— source vertex id (0 ≤ source < vcount()).target— sink vertex id (0 ≤ target < vcount(),target != source).capacity— optional per-edge capacity in the graph’s edge-id order. WhenNone, each edge contributes unit capacity. WhenSome(c),c.len()must equalgraph.ecount(), and every entry must be finite and≥ 0.
§Returns
An StMincut whose
valueequals the maximumsource → targetflow (matchesmax_flow_value/st_mincut_valuewithin1e-12).cutlists original edge ids whose removal disconnectssourcefromtarget. Sum ofcapacity[cut[i]](orcut.len()whencapacityisNone) equalsvaluewithin tolerance.partitionis the source-sideS(always containssource, never containstargetunless the graph is so degenerate that they’re already separated by the empty cut).partition2isV \ S(always containstarget).
Both partitions list vertex ids in ascending order. partition and
partition2 together cover every vertex exactly once.
§Errors
Same as max_flow_value:
IgraphError::VertexOutOfRangeifsourceortargetis outside[0, vcount()).IgraphError::InvalidArgumentifsource == target, the capacity slice length differs fromecount(), or any capacity is negative / non-finite.
§Examples
use rust_igraph::{Graph, st_mincut};
// 0 → 1 (cap 5) → 2 (cap 2) → 3 (cap 7).
// Unique bottleneck arc (1, 2): cut = [1], partition = [0, 1].
let mut g = Graph::new(4, true).unwrap();
g.add_edge(0, 1).unwrap();
g.add_edge(1, 2).unwrap();
g.add_edge(2, 3).unwrap();
let cut = st_mincut(&g, 0, 3, Some(&[5.0, 2.0, 7.0])).unwrap();
assert!((cut.value - 2.0).abs() < 1e-12);
assert_eq!(cut.cut, vec![1]);
assert_eq!(cut.partition, vec![0, 1]);
assert_eq!(cut.partition2, vec![2, 3]);