Skip to main content

st_mincut

Function st_mincut 

Source
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:

  1. Calls the crate-private max_flow_with_residual backend (the shared Dinic entry point that also powers max_flow_value) to obtain both the flow value and the final residual network.
  2. Runs one BFS from source in the residual graph (following only arcs with strictly positive residual capacity). The set of reachable vertices is precisely the source-side S of a minimum s-t cut (max-flow / min-cut duality, Ford-Fulkerson 1956). The complement is partition2.
  3. 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 points S → 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. When None, each edge contributes unit capacity. When Some(c), c.len() must equal graph.ecount(), and every entry must be finite and ≥ 0.

§Returns

An StMincut whose

  • value equals the maximum source → target flow (matches max_flow_value / st_mincut_value within 1e-12).
  • cut lists original edge ids whose removal disconnects source from target. Sum of capacity[cut[i]] (or cut.len() when capacity is None) equals value within tolerance.
  • partition is the source-side S (always contains source, never contains target unless the graph is so degenerate that they’re already separated by the empty cut).
  • partition2 is V \ S (always contains target).

Both partitions list vertex ids in ascending order. partition and partition2 together cover every vertex exactly once.

§Errors

Same as max_flow_value:

§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]);