Skip to content

Algorithms (Advanced) | Computer Science

Network flow models the movement of commodities through capacity-constrained networks. The max-flow min-cut theorem reveals a deep duality: the maximum flow equals the minimum cut, connecting optimisation to combinatorial structure. Ford-Fulkerson finds augmenting paths in the residual graph, pushing flow until no more can be sent. Linear programming generalises optimisation to continuous variables, and approximation algorithms provide provably near-optimal solutions when exact algorithms are too slow.

A flow network is a directed graph G=(V,E)G = (V, E) with:

  • A source sVs \in V and a sink tVt \in V.
  • A capacity function c:ER0c : E \to \mathbb{R}_{\geq 0}.
  • For every edge (u,v)E(u, v) \in EThe reverse edge (v,u)E(v, u) \notin E (we can add reverse edges with capacity 0).

A flow is a function f:V×VR0f : V \times V \to \mathbb{R}_{\geq 0} satisfying:

  1. Capacity constraint: 0f(u,v)c(u,v)0 \leq f(u, v) \leq c(u, v) for all (u,v)E(u, v) \in E.
  2. Flow conservation: vVf(v,u)=vVf(u,v)\sum_{v \in V} f(v, u) = \sum_{v \in V} f(u, v) for all uV{s,t}u \in V \setminus \{s, t\}.

The value of a flow is f=vVf(s,v)vVf(v,s)=vVf(v,t)vVf(t,v)|f| = \sum_{v \in V} f(s, v) - \sum_{v \in V} f(v, s) = \sum_{v \in V} f(v, t) - \sum_{v \in V} f(t, v).

Theorem 1.1 (Max-Flow Min-Cut). The maximum value of a flow from ss to tt equals the minimum capacity of an ss-tt cut.

Proof. Let ff^* be a maximum flow. Let SS be the set of vertices reachable from ss in the residual graph GfG_f (the graph with edges of positive residual capacity). Since ff^* is maximum, tSt \notin S. The cut (S,VS)(S, V \setminus S) has capacity equal to f|f^*|:

  1. Every edge from SS to VSV \setminus S is saturated by ff^* (otherwise it would have residual capacity and VSV \setminus S would contain a vertex reachable from ss).
  2. Every edge from VSV \setminus S to SS carries zero flow (otherwise the reverse edge in the residual graph would provide a path from ss into SS).

Therefore f=uS,vVSf(u,v)uS,vVSf(v,u)=uS,vVSc(u,v)|f^*| = \sum_{u \in S, v \in V \setminus S} f^*(u, v) - \sum_{u \in S, v \in V \setminus S} f^*(v, u) = \sum_{u \in S, v \in V \setminus S} c(u, v).

Since any flow has value at most the capacity of any cut, and we have found a cut with capacity f|f^*|The maximum flow equals the minimum cut. \blacksquare

The Ford-Fulkerson method iteratively finds augmenting paths in the residual graph and pushes flow along them.

Residual capacity: cf(u,v)=c(u,v)f(u,v)c_f(u, v) = c(u, v) - f(u, v) (forward edge) or cf(u,v)=f(v,u)c_f(u, v) = f(v, u) (reverse edge).

Algorithm:

Ford-Fulkerson(G, s, t, c):
initialize f(u, v) = 0 for all (u, v)
while there exists an augmenting path P from s to t in G_f:
c_f(P) = min{c_f(u, v) : (u, v) in P}
for each (u, v) in P:
f(u, v) += c_f(P)
f(v, u) -= c_f(P)
return f

Theorem 1.2. If all capacities are integers, the Ford-Fulkerson method terminates with a maximum flow after at most f|f^*| augmentations, where f|f^*| is the value of the maximum flow.

Proof. Each augmentation increases the flow value by at least 1 (since capacities are integers, the residual capacity of any path is at least 1). The flow value cannot exceed f|f^*| So at most f|f^*| augmentations occur. \blacksquare

Corollary. With integer capacities, the running time is O(Ef)O(E \cdot |f^*|).

Note on irrational capacities. If capacities are irrational, Ford-Fulkerson may not terminate. It may converge to a value strictly less than the maximum.

The Edmonds-Karp algorithm is Ford-Fulkerson where augmenting paths are found using BFS (shortest augmenting path in terms of number of edges).

Theorem 1.3. Edmonds-Karp runs in O(VE2)O(VE^2) time.

Proof. The key insight is that each edge can become a “critical edge” (the bottleneck of an augmenting path) at most O(V)O(V) times. Each time an edge (u,v)(u, v) becomes critical, the distance from ss to uu in the residual graph strictly increases. Since the distance from ss to any vertex is at most V1V - 1Each edge can become critical at most V/2V/2 times (the distance increases by at least 2). With EE edges, the total number of augmentations is O(VE)O(VE). Each BFS takes O(E)O(E)Giving O(VE2)O(VE^2). \blacksquare

Worked Example: Edmonds-Karp Maximum Flow

Find the maximum flow from ss to tt in the following network:

Edges with capacities: s10as \xrightarrow{10} a, s8bs \xrightarrow{8} b, a5ba \xrightarrow{5} b, a7ca \xrightarrow{7} c, a8ta \xrightarrow{8} t, b10cb \xrightarrow{10} c, b4tb \xrightarrow{4} t, c6tc \xrightarrow{6} t.

Iteration 1: BFS finds sats \to a \to t. Bottleneck = 8. Push 8. Residual: s2as \xrightarrow{2} a, a8ta \xrightarrow{8} t becomes a0ta \xrightarrow{0} t (saturated). Reverse t8at \xrightarrow{8} a. Flow: f=8|f| = 8.

Iteration 2: BFS finds sacts \to a \to c \to t. Bottleneck = min(2,7,6)=2\min(2, 7, 6) = 2. Push 2. Residual: s0as \xrightarrow{0} a (saturated), a5ca \xrightarrow{5} c, c4tc \xrightarrow{4} t. Reverse edges: c2ac \xrightarrow{2} a, t2ct \xrightarrow{2} c. Flow: f=10|f| = 10.

Iteration 3: BFS from ss: s8bs \xrightarrow{8} b. From bb: b5ab \xrightarrow{5} a (reverse, residual 5 from a5ba \xrightarrow{5} b… Wait, let me track the residual graph more carefully).

Actually, let me restart with a cleaner approach.

Initial flow f=0f = 0 for all edges.

Residual graph GfG_f (all edges with residual capacity > 0): sas \to a (10), sbs \to b (8), aba \to b (5), aca \to c (7), ata \to t (8), bcb \to c (10), btb \to t (4), ctc \to t (6).

Augmentation 1: BFS shortest path: sats \to a \to t. Residual capacity = min(10,8)=8\min(10, 8) = 8.

Flow after: f(s,a)=8f(s,a) = 8, f(a,t)=8f(a,t) = 8. Residual: s2as \xrightarrow{2} a, a8ta \xrightarrow{8} t (0, saturated). Reverse: a8sa \xrightarrow{8} s, t8at \xrightarrow{8} a.

Augmentation 2: BFS: sbts \to b \to t. Residual = min(8,4)=4\min(8, 4) = 4.

Flow after: f(s,b)=4f(s,b) = 4, f(b,t)=4f(b,t) = 4. Residual: s4bs \xrightarrow{4} b, b0tb \xrightarrow{0} t. Reverse: b4sb \xrightarrow{4} s, t4bt \xrightarrow{4} b.

Augmentation 3: BFS: sbcts \to b \to c \to t. Residual = min(4,10,6)=4\min(4, 10, 6) = 4.

Flow: f(s,b)=8f(s,b) = 8, f(b,c)=4f(b,c) = 4, f(c,t)=4f(c,t) = 4. Residual: s0bs \xrightarrow{0} b. b6cb \xrightarrow{6} c, c2tc \xrightarrow{2} t. Reverse: c4bc \xrightarrow{4} b, t4ct \xrightarrow{4} c.

Augmentation 4: BFS: sabcts \to a \to b \to c \to t. Residual = min(2,5,6,2)=2\min(2, 5, 6, 2) = 2.

Flow: f(s,a)=10f(s,a) = 10, f(a,b)=2f(a,b) = 2, f(b,c)=6f(b,c) = 6, f(c,t)=6f(c,t) = 6. Residual: s0as \xrightarrow{0} a. a3ba \xrightarrow{3} b, a7ca \xrightarrow{7} c. b4cb \xrightarrow{4} c. c0tc \xrightarrow{0} t.

Augmentation 5: BFS from ss: ss has no outgoing edges with residual capacity. Wait, sas \to a has 0 residual, sbs \to b has 0 residual. But we have reverse edges!

ss has reverse edge from bb: b8sb \xrightarrow{8} s. But we are searching from ssNot to ss. The reverse edge a8sa \xrightarrow{8} s goes into ssWhich is irrelevant for BFS from ss.

Hmm, actually BFS from ss can only follow outgoing edges. ss“s outgoing residual edges are: s0as \xrightarrow{0} a (no), s0bs \xrightarrow{0} b (no). There are no reverse edges from ss to anywhere.

So there is no augmenting path. The algorithm terminates.

Maximum flow value: f=f(s,a)+f(s,b)=10+8=18|f| = f(s,a) + f(s,b) = 10 + 8 = 18.

Verify with min-cut: The set S={s}S = \{s\}, T=VST = V \setminus S. Cut capacity = c(s,a)+c(s,b)=10+8=18c(s,a) + c(s,b) = 10 + 8 = 18. Since the flow equals the cut, it is maximum.

But wait, let me verify the flow conservation at each node:

  • Node aa: inflow = f(s,a)=10f(s,a) = 10. Outflow = f(a,b)+f(a,c)+f(a,t)=2+0+8=10f(a,b) + f(a,c) + f(a,t) = 2 + 0 + 8 = 10. OK.
  • Node bb: inflow = f(s,b)+f(a,b)=8+2=10f(s,b) + f(a,b) = 8 + 2 = 10. Outflow = f(b,c)+f(b,t)=6+4=10f(b,c) + f(b,t) = 6 + 4 = 10. OK.
  • Node cc: inflow = f(a,c)+f(b,c)=0+6=6f(a,c) + f(b,c) = 0 + 6 = 6. Outflow = f(c,t)=6f(c,t) = 6. OK.

Maximum flow = 18.

Bipartite matching. Given a bipartite graph with partitions LL and RRCreate a flow network: source ss connected to all uLu \in L with capacity 1, all edges (u,v)(u, v) with uLu \in L, vRv \in R have capacity 1, all vRv \in R connected to sink tt with capacity 1. Maximum flow = maximum matching.

Theorem 1.4. The maximum matching in a bipartite graph with L=n1|L| = n_1 and R=n2|R| = n_2 can be found in O(VE2)O(V E^2) time using Edmonds-Karp.

Hall’s Theorem via max-flow. A bipartite graph has a matching covering LL if and only if N(S)S|N(S)| \geq |S| for all SLS \subseteq L. This follows from max-flow min-cut: the cut ({s}SN(S),)(\{s\} \cup S \cup N(S), \ldots) has capacity LS+N(S)|L| - |S| + |N(S)|. Hall’s condition ensures this is at least L|L|.

Other applications:

  • Image segmentation: Pixels are vertices, edges between adjacent pixels have capacity proportional to similarity. Source connects to foreground seeds, sink to background seeds.
  • Project selection: Max-flow on a network encoding project profits (as source edges) and costs (as sink edges) finds the optimal set of projects.
  • Baseball elimination: Determine if a team can still win its division by constructing a flow network.

In a minimum cost maximum flow problem, each edge (u,v)(u, v) has a cost w(u,v)w(u, v) per unit of flow, in addition to its capacity. The goal is to find a maximum flow of minimum total cost.

Total cost: cost(f)=(u,v)Ef(u,v)w(u,v)\mathrm{cost}(f) = \sum_{(u,v) \in E} f(u,v) \cdot w(u,v).

Algorithm (Successive Shortest Paths):

  1. Start with zero flow.
  2. While an augmenting path exists, find the shortest (minimum cost) path from ss to tt in the residual graph (using edge costs as weights, with reverse edges having negative costs).
  3. Push as much flow as possible along this path.
  4. Update the residual graph.

Theorem 1.5. If all edge costs are non-negative and there are no negative-cost cycles in the residual graph, the successive shortest paths algorithm finds the minimum cost maximum flow.

Running time: O(FElogV)O(F \cdot E \log V) where FF is the maximum flow value (using Dijkstra for shortest paths). With capacity scaling, this improves to O(ElogV(E+VlogV)log(UC))O(E \log V \cdot (E + V \log V) \cdot \log(UC)) where UU is the maximum capacity and CC the maximum cost.

Worked Example: Minimum Cost Flow

Network with costs (shown as capacity/cost):

s3/2as \xrightarrow{3/2} a, s2/3bs \xrightarrow{2/3} b, a2/1ba \xrightarrow{2/1} b, a3/4ta \xrightarrow{3/4} t, b1/2tb \xrightarrow{1/2} t, b2/1tb \xrightarrow{2/1} t.

Find minimum cost flow of value 4.

Augmentation 1: Shortest path from ss to tt (by cost):

  • sats \to a \to t: cost 2+4=62 + 4 = 6
  • sbts \to b \to t: cost 3+2=53 + 2 = 5 (via first btb \to t edge)
  • sbts \to b \to t: cost 3+1=43 + 1 = 4 (via second btb \to t edge)
  • sabts \to a \to b \to t: cost 2+1+2=52 + 1 + 2 = 5 (or 2+1+1=42 + 1 + 1 = 4)

Shortest: sabts \to a \to b \to t via second btb \to t edge, cost 2+1+1=42 + 1 + 1 = 4. Bottleneck = min(3,2,2)=2\min(3, 2, 2) = 2. Push 2. Cost so far: 2×4=82 \times 4 = 8.

Augmentation 2: Residual graph. Shortest path from ss to tt:

  • sbts \to b \to t (first edge): cost 3+2=53 + 2 = 5Bottleneck min(2,1)=1\min(2, 1) = 1. Push 1. Cost: 8+5=138 + 5 = 13.

Augmentation 3: Residual. Shortest path: sats \to a \to t: cost 2+4=62 + 4 = 6Bottleneck min(1,3)=1\min(1, 3) = 1. Push 1. Cost: 13+6=1913 + 6 = 19.

Total flow = 2+1+1=42 + 1 + 1 = 4. Total cost = 19.

Flow assignment: f(s,a)=3f(s,a) = 3, f(s,b)=1f(s,b) = 1, f(a,b)=2f(a,b) = 2, f(a,t)=1f(a,t) = 1, f(b,t)=3f(b,t) = 3 (1 on first edge, 2 on second).

Verify: inflow at ss = 3+1=43 + 1 = 4 = outflow at tt = 1+3=41 + 3 = 4. ✓ Node aa: inflow = 3, outflow = 2+1=32 + 1 = 3. ✓ Node bb: inflow = 1+2=31 + 2 = 3Outflow = 1+2=31 + 2 = 3. ✓

2.1 Interval Scheduling and Weighted Interval Scheduling

Section titled “2.1 Interval Scheduling and Weighted Interval Scheduling”

Weighted interval scheduling. Given nn intervals [si,fi)[s_i, f_i) with weights wiw_iFind a maximum-weight subset of non-overlapping intervals.

DP formulation. Sort intervals by finish time f1f2fnf_1 \leq f_2 \leq \cdots \leq f_n. Define p(j)p(j) = the largest index i<ji < j such that interval ii does not overlap interval jj (i.e., fisjf_i \leq s_j).

OPT(j)=max{wj+OPT(p(j)), OPT(j1)}OPT(j) = \max\{w_j + OPT(p(j)),\ OPT(j-1)\}

Base case: OPT(0)=0OPT(0) = 0.

Running time: O(nlogn)O(n \log n) for sorting + computing p(j)p(j) using binary search. O(n)O(n) for the DP itself. Total: O(nlogn)O(n \log n).

Theorem 2.1. The weighted interval scheduling DP correctly computes the maximum weight of non-overlapping intervals.

Proof. By strong induction on jj. For the optimal solution for intervals {1,,j}\{1, \ldots, j\}Either interval jj is included (then the remaining solution is optimal for {1,,p(j)}\{1, \ldots, p(j)\}By optimal substructure) or it is not (then the solution is optimal for {1,,j1}\{1, \ldots, j-1\}). The recurrence considers both cases. \blacksquare

Worked Example: Weighted Interval Scheduling

Intervals (already sorted by finish time):

iisis_ifif_iwiw_i
1035
2146
3268
4474
5693
67107

Compute p(j)p(j) using binary search:

  • p(1)=0p(1) = 0 (no interval before 1 finishes by s1=0s_1 = 0)
  • p(2)=0p(2) = 0 (f1=3>s2=1f_1 = 3 > s_2 = 1; no interval finishes by t=1t = 1)
  • p(3)=0p(3) = 0 (f2=4>s3=2f_2 = 4 > s_3 = 2)
  • p(4)=2p(4) = 2 (f2=4s4=4f_2 = 4 \leq s_4 = 4; f3=6>4f_3 = 6 > 4)
  • p(5)=3p(5) = 3 (f3=6s5=6f_3 = 6 \leq s_5 = 6)
  • p(6)=4p(6) = 4 (f4=7s6=7f_4 = 7 \leq s_6 = 7; f5=9>7f_5 = 9 > 7)

DP table:

  • OPT(0)=0OPT(0) = 0
  • OPT(1)=max(5+OPT(0),OPT(0))=max(5,0)=5OPT(1) = \max(5 + OPT(0), OPT(0)) = \max(5, 0) = 5
  • OPT(2)=max(6+OPT(0),OPT(1))=max(6,5)=6OPT(2) = \max(6 + OPT(0), OPT(1)) = \max(6, 5) = 6
  • OPT(3)=max(8+OPT(0),OPT(2))=max(8,6)=8OPT(3) = \max(8 + OPT(0), OPT(2)) = \max(8, 6) = 8
  • OPT(4)=max(4+OPT(2),OPT(3))=max(4+6,8)=10OPT(4) = \max(4 + OPT(2), OPT(3)) = \max(4 + 6, 8) = 10
  • OPT(5)=max(3+OPT(3),OPT(4))=max(3+8,10)=11OPT(5) = \max(3 + OPT(3), OPT(4)) = \max(3 + 8, 10) = 11
  • OPT(6)=max(7+OPT(4),OPT(5))=max(7+10,11)=17OPT(6) = \max(7 + OPT(4), OPT(5)) = \max(7 + 10, 11) = 17

Maximum weight = OPT(6)=17OPT(6) = 17.

Reconstruct: OPT(6)=7+OPT(4)=17OPT(6) = 7 + OPT(4) = 17. Include interval 6. OPT(4)=4+OPT(2)=10OPT(4) = 4 + OPT(2) = 10. Include interval 4. OPT(2)=6+OPT(0)=6OPT(2) = 6 + OPT(0) = 6. Include interval 2.

Solution: intervals 2, 4, 6 with weights 6, 4, 7 = 17. Verify no overlaps: [1,4), [4,7), [7,10). ✓

Given nn keys k1<k2<<knk_1 < k_2 < \cdots < k_n with search probabilities p1,p2,,pnp_1, p_2, \ldots, p_n and dummy key probabilities q0,q1,,qnq_0, q_1, \ldots, q_n (for searches between keys), find a BST minimising the expected search cost.

Expected cost: E[cost]=i=1n(d(ki)+1)pi+j=0n(d(dj)+1)qjE[\text{cost}] = \sum_{i=1}^{n} (d(k_i) + 1) \cdot p_i + \sum_{j=0}^{n} (d(d_j) + 1) \cdot q_j

Where dd is the depth of the node and djd_j is the depth of dummy key jj.

DP formulation: Let e[i,j]e[i, j] be the expected search cost for keys ki,,kjk_i, \ldots, k_j.

e[i,j]={qi1ifj=i1minr=ij{e[i,r1]+e[r+1,j]+w(i,j)}ifije[i, j] = \begin{cases} q_{i-1} & \text{if} j = i - 1 \\ \min_{r=i}^{j}\{e[i, r-1] + e[r+1, j] + w(i, j)\} & \text{if} i \leq j \end{cases}

Where w(i,j)=l=ijpl+l=i1jqlw(i, j) = \sum_{l=i}^{j} p_l + \sum_{l=i-1}^{j} q_l is the total probability of the subtree.

Running time: O(n3)O(n^3) (Knuth’s optimisation reduces this to O(n2)O(n^2) when the cost function satisfies the quadrangle inequality).

Theorem 2.2 (Knuth’s Optimisation). If the optimal root of e[i,j]e[i, j] is monotone (i.e., root[i,j1]root[i,j]root[i+1,j]\mathrm{root}[i, j-1] \leq \mathrm{root}[i, j] \leq \mathrm{root}[i+1, j]), then the DP can be computed in O(n2)O(n^2) time by restricting the search range for the root.

Worked Example: Optimal BST

Keys: k1=1k_1 = 1, k2=2k_2 = 2, k3=3k_3 = 3. Probabilities: p1=0.3p_1 = 0.3, p2=0.2p_2 = 0.2, p3=0.1p_3 = 0.1. Dummy probabilities: q0=0.1q_0 = 0.1, q1=0.1q_1 = 0.1, q2=0.1q_2 = 0.1, q3=0.1q_3 = 0.1.

Compute w(i,j)w(i, j):

  • w(0,0)=q0=0.1w(0, 0) = q_0 = 0.1
  • w(1,1)=p1+q0+q1=0.3+0.1+0.1=0.5w(1, 1) = p_1 + q_0 + q_1 = 0.3 + 0.1 + 0.1 = 0.5
  • w(2,2)=p2+q1+q2=0.2+0.1+0.1=0.4w(2, 2) = p_2 + q_1 + q_2 = 0.2 + 0.1 + 0.1 = 0.4
  • w(3,3)=p3+q2+q3=0.1+0.1+0.1=0.3w(3, 3) = p_3 + q_2 + q_3 = 0.1 + 0.1 + 0.1 = 0.3
  • w(1,2)=p1+p2+q0+q1+q2=0.3+0.2+0.1+0.1+0.1=0.8w(1, 2) = p_1 + p_2 + q_0 + q_1 + q_2 = 0.3 + 0.2 + 0.1 + 0.1 + 0.1 = 0.8
  • w(2,3)=p2+p3+q1+q2+q3=0.2+0.1+0.1+0.1+0.1=0.6w(2, 3) = p_2 + p_3 + q_1 + q_2 + q_3 = 0.2 + 0.1 + 0.1 + 0.1 + 0.1 = 0.6
  • w(1,3)=0.3+0.2+0.1+0.1+0.1+0.1+0.1=1.0w(1, 3) = 0.3 + 0.2 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 = 1.0

Compute e[i,j]e[i, j]:

  • e[0,0]=q0=0.1e[0, 0] = q_0 = 0.1

  • e[1,1]=w(1,1)=0.5e[1, 1] = w(1,1) = 0.5

  • e[2,2]=w(2,2)=0.4e[2, 2] = w(2,2) = 0.4

  • e[3,3]=w(3,3)=0.3e[3, 3] = w(3,3) = 0.3

  • e[1,2]e[1, 2]: root r=1r = 1: e[1,0]+e[2,2]+w(1,2)=0.1+0.4+0.8=1.3e[1,0] + e[2,2] + w(1,2) = 0.1 + 0.4 + 0.8 = 1.3. root r=2r = 2: e[1,1]+e[3,2]+w(1,2)=0.5+0.1+0.8=1.4e[1,1] + e[3,2] + w(1,2) = 0.5 + 0.1 + 0.8 = 1.4. Minimum: e[1,2]=1.3e[1, 2] = 1.3Root = 1.

  • e[2,3]e[2, 3]: root r=2r = 2: e[2,1]+e[3,3]+w(2,3)=0.1+0.3+0.6=1.0e[2,1] + e[3,3] + w(2,3) = 0.1 + 0.3 + 0.6 = 1.0. root r=3r = 3: e[2,2]+e[4,3]+w(2,3)=0.4+0.1+0.6=1.1e[2,2] + e[4,3] + w(2,3) = 0.4 + 0.1 + 0.6 = 1.1. Minimum: e[2,3]=1.0e[2, 3] = 1.0Root = 2.

  • e[1,3]e[1, 3]: root r=1r = 1: e[1,0]+e[2,3]+w(1,3)=0.1+1.0+1.0=2.1e[1,0] + e[2,3] + w(1,3) = 0.1 + 1.0 + 1.0 = 2.1. root r=2r = 2: e[1,1]+e[3,3]+w(1,3)=0.5+0.3+1.0=1.8e[1,1] + e[3,3] + w(1,3) = 0.5 + 0.3 + 1.0 = 1.8. root r=3r = 3: e[1,2]+e[4,3]+w(1,3)=1.3+0.1+1.0=2.4e[1,2] + e[4,3] + w(1,3) = 1.3 + 0.1 + 1.0 = 2.4. Minimum: e[1,3]=1.8e[1, 3] = 1.8Root = 2.

Optimal BST: root = k2=2k_2 = 2Left child = k1=1k_1 = 1Right child = k3=3k_3 = 3. Expected search cost: 1.8.

Bitmask DP is used when the state involves a subset of nn elements (with n20n \leq 20 ). The bitmask S{0,,n1}S \subseteq \{0, \ldots, n-1\} is represented as an integer where bit ii is set iff iSi \in S.

The Travelling Salesman Problem (TSP). Find the shortest tour visiting all nn cities exactly once and returning to the start.

dp[S][i]=minimumcosttovisitallcitiesinS startingfromcity0,endingatcityidp[S][i] = \text{minimum} cost to visit all cities in S \text{ starting} from city 0, ending at city i

Recurrence:

dp[S][i]=minjS,ji{dp[S{i}][j]+dist(j,i)}dp[S][i] = \min_{j \in S, j \neq i} \{dp[S \setminus \{i\}][j] + \text{dist}(j, i)\}

Base case: dp[{0}][0]=0dp[\{0\}][0] = 0, dp[S][i]=dp[S][i] = \infty for iSi \notin S.

Answer: mini{dp[{0,1,,n1}][i]+dist(i,0)}\min_i \{dp[\{0, 1, \ldots, n-1\}][i] + \text{dist}(i, 0)\}.

Running time: O(2nn2)O(2^n \cdot n^2).

Theorem 2.3. The bitmask DP solves TSP exactly in O(2nn2)O(2^n \cdot n^2) time and O(2nn)O(2^n \cdot n) space.

When the recurrence has the form dp[i][j]=mink<j{dp[i1][k]+C(k,j)}dp[i][j] = \min_{k < j} \{dp[i-1][k] + C(k, j)\} and the optimal kk is monotone in jjWe can use divide and conquer to compute each row in O(nlogn)O(n \log n) instead of O(n2)O(n^2).

Theorem 2.4 (Monge / Quadrangle Inequality). If CC satisfies the quadrangle inequality C(a,c)+C(b,d)C(a,d)+C(b,c)C(a, c) + C(b, d) \leq C(a, d) + C(b, c) for all abcda \leq b \leq c \leq d Then the optimal split point is monotone.

When the recurrence is dp[i]=minj{dp[j]+a[i]b[j]+c[j]}dp[i] = \min_j \{dp[j] + a[i] \cdot b[j] + c[j]\} And the lines y=b[j]x+(dp[j]+c[j])y = b[j] \cdot x + (dp[j] + c[j]) are added in order of slope, we can maintain a convex hull of lines and query in O(logn)O(\log n) per step.

Total time: O(nlogn)O(n \log n) instead of O(n2)O(n^2).