A circulation is a flow with no source or sink — conservation holds everywhere. With lower bounds on edges and demands at vertices, feasibility becomes a genuine question, and one that a plain max-flow solver can answer after a standard transformation.
The problem
Each edge has bounds . Each vertex has a demand (positive = must consume, negative = must produce), and conservation reads
Does a feasible exist?
Transformation 1: eliminate lower bounds
Set with . Sending units along every edge unconditionally changes each vertex’s balance, so fold that into the demands:
Now every edge has bounds and the demands have absorbed the mandatory flow.
Transformation 2: demands to a max-flow instance
Add a super-source and super-sink :
- for each with (excess supply): edge with capacity ;
- for each with (excess demand): edge with capacity .
A feasible circulation exists iff the max flow from to saturates every edge out of (equivalently, equals ).
The actual circulation is where is the flow found.
// after computing d'[] and residual capacities c-l
long long need = 0;
for (int v = 0; v < n; v++) {
if (dp[v] < 0) { din.addEdge(S, v, -dp[v]); }
else if (dp[v] > 0) { din.addEdge(v, T, dp[v]); need += dp[v]; }
}
bool feasible = (din.maxflow(S, T) == need);- flow with lower bounds
To find an - flow (not a circulation) respecting lower bounds:
- Add an edge with capacity (and lower bound 0) — this converts the flow into a circulation.
- Run the feasibility test above.
- For the maximum such flow: after achieving feasibility, delete the edge and run max flow from to on the residual graph, adding to the value already carried.
- For the minimum such flow: instead run max flow from to on the residual and subtract.
Where lower bounds appear
| Problem | Lower bound meaning |
|---|---|
| ”Every task must be done at least once” | on the task edge |
| ”Each machine runs at least hours” | |
| Chinese postman / route covering every road | per road |
| Matrix rounding (row/column sums preserved) | , |
| Scheduling with minimum staffing per shift | = required staff |
| Flow decomposition into exactly paths | lower bound on the source edge |
Matrix rounding is the classic: given a real matrix, round every entry up or down so that all row sums and column sums are also rounded versions of the originals. Model rows as sources, columns as sinks, and each cell as an edge with , . A feasible circulation is exactly a valid rounding — and one always exists, which is a pleasing constructive proof.
Minimum cost version
Combine with min-cost flow: after the lower-bound transformation, run MCMF instead of max flow. The mandatory flow contributes a fixed that you add back at the end. Watch for negative costs, which need Bellman-Ford potentials or an initial negative-cycle cancellation.
See also: Maximum Flow · Min-Cost Flow · Eulerian Path