Flow with Lower and Upper Bounds

Read Maximum flow before reading this article, and make sure you are familiar with the maximum-flow algorithm.

Overview

In essence, a flow network with lower and upper bounds assigns an upper bound c(u,v)c(u,v) and a lower bound b(u,v)b(u,v) to every edge. In other words, a feasible flow must satisfy b(u,v)≤f(u,v)≤c(u,v)b(u,v) \leq f(u,v) \leq c(u,v). At the same time, flow conservation must hold at every vertex other than the source and sink.

Depending on the requirements of the problem, flow networks with lower and upper bounds can be used to solve different problems.

Feasible flow with lower and upper bounds and no source or sink

Given a flow network GG with no source or sink, determine whether there is a way to assign a flow to every edge so that all edge bounds and flow conservation at every vertex are satisfied.

Assume that every edge initially carries b(u,v)b(u,v) units of flow, and call this the initial flow. In the new graph, also add an edge from uu to vv with capacity c(u,v)−b(u,v)c(u,v) - b(u,v). We will make adjustments in this new graph.

Because maximum flow requires the initial flow to satisfy flow conservation (maximum flow can be viewed as a lower-bounded maximum-flow problem with lower bound 00), the constructed initial flow may fail to satisfy flow conservation. Suppose that, at some vertex, initial inflow minus initial outflow is MM.

If M=0M=0, flow is conserved and no auxiliary edge is needed.

If M>0M>0, inflow is too large. Create an auxiliary source S′S' and an auxiliary edge from S′S' to this vertex with flow MM.

If M<0M<0, outflow is too large. Create an auxiliary sink T′T' and an auxiliary edge from this vertex to T′T' with flow −M-M.

If all auxiliary edges are saturated, the flow-conservation condition at this vertex can be satisfied; otherwise it cannot. (Only after the original graph is augmented with the auxiliary flow will flow conservation in the original graph hold.)

After constructing the graph, run maximum flow from S′S' to T′T'. A feasible flow exists if and only if all edges leaving S′S' are saturated.

Example

luogu P14578 [Template] Feasible flow with lower and upper bounds and no source or sink

Given a directed graph GG with nn vertices and mm directed edges, where each edge has a flow lower bound lil_i and upper bound rir_i.

Construct an assignment of flows wiw_i satisfying the flow bounds li≤wi≤ril_i\leq w_i\leq r_i and flow conservation at every vertex, that is, inflow equals outflow at every vertex. Or report that no solution exists.

Reference code
#include <iostream>
#include <queue>
using namespace std;
constexpr int MAXN = 3e4 + 10;
constexpr int INF = 1e9 + 10;
int n, m, s = 0, t;
int ecnt = 1, head[MAXN], dep[MAXN], now[MAXN], l[MAXN], d[MAXN], id[MAXN];

struct edge {
  int to, nxt, w;
} e[MAXN];

void add_edge(int u, int v, int w) {
  e[++ecnt] = {v, head[u], w};
  head[u] = ecnt;
}

void init() {
  for (int i = 0; i <= n + 1; i++) dep[i] = 0;
  for (int i = 0; i <= n + 1; i++) now[i] = head[i];
}

int bfs() {
  init();
  queue<int> q;
  q.push(s);
  dep[s] = 1;
  while (!q.empty()) {
    int x = q.front();
    q.pop();
    for (int i = head[x]; i; i = e[i].nxt) {
      int v = e[i].to;
      if (dep[v] || !e[i].w) continue;
      dep[v] = dep[x] + 1;
      q.push(v);
    }
  }
  return dep[t];
}

int dfs(int x, int flow) {
  if (x == t) return flow;
  int ret = 0;
  for (int i = now[x]; i; i = e[i].nxt) {
    now[x] = i;
    int v = e[i].to;
    if (dep[v] != dep[x] + 1 || !e[i].w) continue;
    int w = dfs(v, min(flow - ret, e[i].w));
    e[i].w -= w;
    e[i ^ 1].w += w;
    ret += w;
    if (ret == flow) return ret;
  }
  return ret;
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  cin >> n >> m;
  s = 0, t = n + 1;
  for (int i = 1; i <= m; i++) {
    int u, v, r;
    cin >> u >> v >> l[i] >> r;
    add_edge(u, v, r - l[i]);
    add_edge(v, u, 0);
    id[i] = ecnt;
    d[v] += l[i];
    d[u] -= l[i];
  }
  long long sum = 0;
  for (int i = 1; i <= n; i++) {
    if (d[i] > 0) {
      add_edge(s, i, d[i]);
      add_edge(i, s, 0);
      sum += d[i];
    } else if (d[i] < 0) {
      add_edge(i, t, -d[i]);
      add_edge(t, i, 0);
    }
  }
  long long ans = 0;
  while (bfs()) ans += dfs(s, INF);
  if (ans < sum) {
    cout << "No\n";
    return 0;
  }
  cout << "Yes\n";
  for (int i = 1; i <= m; i++) cout << e[id[i]].w + l[i] << "\n";
  return 0;
}

Feasible flow with lower and upper bounds and a source and sink

Given a flow network GG with a source and sink, determine whether there is a way to assign a flow to every edge so that all edge bounds and flow conservation at every vertex other than the source and sink are satisfied.

Assume the source is SS and the sink is TT.

Add an edge from TT to SS with upper bound ∞\infty and lower bound 00. This reduces the problem to a feasible-flow problem with lower and upper bounds and no source or sink.

If a solution exists, the feasible-flow value from SS to TT equals the flow on the added edge from TT to SS.

Maximum flow with lower and upper bounds and a source and sink

Given a flow network GG with a source and sink, determine whether there is a way to assign a flow to every edge so that all edge bounds and flow conservation at every vertex other than the source and sink are satisfied. If so, find the maximum possible flow value.

Find any feasible flow in the network. If none exists, stop immediately.

Otherwise, remove all auxiliary edges and consider the resulting residual network.

Run maximum flow from SS to TT once more in the residual network. The answer is the feasible-flow value plus this additional maximum-flow value.

A very easy mistake to make

Run the maximum flow from SS to TT directly on the residual network obtained after running the feasible-flow algorithm with lower and upper bounds and a source and sink.

Never run it on the original flow network.

Minimum flow with lower and upper bounds and a source and sink

Given a flow network GG with a source and sink, determine whether there is a way to assign a flow to every edge so that all edge bounds and flow conservation at every vertex other than the source and sink are satisfied. If so, find the minimum possible flow value.

Similarly, consider removing unnecessary flow from the residual network.

Find any feasible flow in the network. If none exists, stop immediately.

Otherwise, remove all auxiliary edges and consider the resulting residual network.

Run maximum flow from TT to SS once more in the residual network. The answer is the feasible-flow value minus this maximum-flow value.

AHOI 2014 Side story

For every story edge from xx to yy with cost vv, set its upper bound to ∞\infty and lower bound to 11.

For every vertex, add an edge to TT with cost cc, upper bound ∞\infty, and lower bound 11.

The source vertex SS has value 11.

This content comes from OI Wiki: Flow with Lower and Upper Bounds. See the original for authors and revision history. AIOJ has adapted the formatting, in-site links, and resource paths.

Content is shared under CC BY-SA 4.0 and SATA license; additional terms are governed by the original notice. Thanks to the OI Wiki authors and contributors; per the SATA terms, please visit the OI Wiki repository and star it to show your support.