Knowledge / Computer Science and Engineering / Minimum spanning trees and network flow

Minimum spanning trees and network flow

Computer Science and Engineering (B.E./B.Tech) · Algorithms · free study notes for exams, placements and interviews

In short

A minimum spanning tree (MST) is the cheapest set of edges that keeps every vertex of a connected weighted undirected graph in one piece, and network flow asks how much material can be pushed from a source to a sink through capacitated directed edges. Both are the "heavy" end of the undergraduate algorithms syllabus: MST is examined through Kruskal, Prim, union-find and the cut/cycle properties, and flow through Ford-Fulkerson, Edmonds-Karp, Dinic and the max-flow min-cut theorem. GATE CS asks 1-2 marks on MST almost every year (uniqueness, edge-weight changes, running times) and flow appears as min-cut, bipartite matching or a modelling question. In Indian hiring, MST and union-find are standard in online rounds at Amazon, Google, Microsoft, Flipkart, Zoho, Samsung R&D and Media.net, while flow modelling turns up in design rounds at quant firms and in competitive-programming-screened roles.

Explained

Spanning trees and the two structural properties

Kruskal's algorithm - sort edges, union-find

  1. Sort all E edges by weight, ascending.
  2. Initialise a disjoint-set structure with V singleton sets.
  3. Scan edges in order; accept edge (u, v) if find(u) != find(v) (it joins two different components), then union(u, v); else reject it as cycle-forming.
  4. Stop after V − 1 accepted edges (or when edges run out - then the graph was disconnected, giving a forest).
  5. Complexity: O(E log E) for the sort, plus O(E α(V)) for the set operations, where α is the inverse Ackermann function (≤ 5 in practice). Overall O(E log E) = O(E log V).
  6. Disjoint-set union (DSU) with two optimisations: union by rank/size (attach the smaller tree under the larger) and path compression (point every node visited by find straight at the root). Together they give near-constant amortised cost.
  7. Greedy and edge-based; naturally handles sparse graphs and pre-sorted or integer weights (counting/radix sort makes it O(E α(V)) when weights are small integers).
  8. Variant: process edges in descending order and delete an edge if the graph stays connected without it - the reverse-delete algorithm, correct but slower.

Prim's algorithm - grow one tree

  1. Pick any start vertex r; set key[r] = 0, key[v] = ∞ for others, parent[v] = NIL.
  2. Repeatedly extract the non-tree vertex with the smallest key and add it (with its parent edge) to the tree.
  3. For every neighbour v of the newly added u that is still outside the tree, if w(u, v) < key[v], set key[v] = w(u, v) and parent[v] = u (decrease-key).
  4. After V extractions the parent array is the MST.
  5. Complexity: adjacency matrix + array of keys → O(V²); adjacency list + binary heap → O(E log V); Fibonacci heap → O(E + V log V) (theoretically best, rarely coded).
  6. Choose Prim with a matrix/array for dense graphs (E ≈ V²), Kruskal for sparse graphs; for E ≈ V² Prim's O(V²) beats Kruskal's O(V² log V).
  7. Prim keeps one connected tree at all times; Kruskal keeps a forest that merges. Prim resembles Dijkstra in shape - the only change is that the key stores the edge weight w(u, v), not the path sum d[u] + w(u, v).
  8. Prim on a disconnected graph finds the MST of only the start vertex's component; restart from each unvisited vertex for a forest.

Boruvka, special cases and MST variants

Flow networks, Ford-Fulkerson and Edmonds-Karp

Max-flow min-cut and modelling

Key points

Formulas and examples

Spanning tree size: |E_T| = V − 1 for a tree on V vertices; a spanning forest with k components has V − k edges.
Number of labelled spanning trees (Cayley): complete graph K_n has nn−2 spanning trees; general graphs by Kirchhoff's matrix-tree theorem = any cofactor of the Laplacian L = D − A.
MST cost: W(T) = Σ_{e ∈ T} w(e), minimised over all spanning trees T.
Kruskal: O(E log E + E α(V)); Prim (heap): O(E log V); Prim (array): O(V²); Boruvka: O(E log V).
Flow value: |f| = Σ_{v} f(s, v) − Σ_{v} f(v, s) = net flow into t.
Cut capacity: c(S, T) = Σ_{u ∈ S, v ∈ T} c(u, v) (only S → T edges counted).
Max-flow min-cut: max_f |f| = min_{(S,T)} c(S, T).
Augmentation bottleneck: Δ = min over edges of the path of residual capacity c_f(u, v) = c(u, v) − f(u, v).
Edmonds-Karp: ≤ O(VE) augmentations ⇒ O(VE²); Dinic: O(V²E), unit capacities O(E√E), bipartite matching O(E√V).
Konig: max matching = min vertex cover (bipartite); max independent set = V − max matching.

Units: edge weights carry whatever the model uses - kilometres of cable, rupees of cost, Mbps of bandwidth, litres/second; capacities and flows share the same unit; costs in MCMF are rupees per unit of flow.

Example 1 - Kruskal by hand with the rejection trace. Graph on 6 vertices (A-F), edges: AB 4, AC 3, BC 1, BD 2, CD 4, CE 2, DE 3, DF 2, EF 3.

StepEdgeWeightActionComponents
1BC1accept{B,C}
2BD2accept{B,C,D}
3CE2accept{B,C,D,E}
4DF2accept{B,C,D,E,F}
5AC3acceptall - 5 edges, stop
-DE 3, EF 3, AB 4, CD 4-would be rejected (cycles)-

MST edges = {BC, BD, CE, DF, AC}, count = 5 = V − 1. Total cost = 1 + 2 + 2 + 2 + 3 = 10.

Example 2 - Prim from A on the same graph.

Example 3 - Ford-Fulkerson and the min cut. Network: s→A 10, s→B 10, A→B 2, A→t 4, B→t 10. (Capacities in Mbps.)

Example 4 - Edmonds-Karp beats bad path choices. Network: s→v 1000, s→w 1000, v→w 1, v→t 1000, w→t 1000.

Example 5 - Bipartite matching by flow (campus placement allocation). 4 students S1-S4, 4 interview slots L1-L4. Preferences: S1:{L1,L2}, S2:{L1}, S3:{L2,L3}, S4:{L3,L4}.

Algorithm choice table

ProblemBest algorithmComplexityWhen
MST, sparse graphKruskal + DSUO(E log E)E ≈ V, edge list given
MST, dense graphPrim + arrayO(V²)E ≈ V², matrix given
MST, parallel/distributedBoruvkaO(E log V)multi-core, MapReduce
Max flow, generalDinicO(V²E)default implementation
Max flow, bipartite matching / unit vertex capsDinic or Hopcroft-KarpO(E√V)matching, vertex-disjoint paths
Max flow, textbook/examEdmonds-KarpO(VE²)small graphs, hand tracing
Min-cost flowSSP + potentialsO(flow · E log V)transportation, assignment
# Kruskal with DSU (union by size + path compression)
def kruskal(n, edges):                      # edges: list of (w, u, v)
    parent = list(range(n)); size = [1]*n
    def find(x):
        while parent[x] != x:
            parent[x] = parent[parent[x]]   # path halving
            x = parent[x]
        return x
    cost, chosen = 0, []
    for w, u, v in sorted(edges):
        ru, rv = find(u), find(v)
        if ru == rv:                        # cycle -> reject (cycle property)
            continue
        if size[ru] < size[rv]: ru, rv = rv, ru
        parent[rv] = ru; size[ru] += size[rv]
        cost += w; chosen.append((u, v, w))
        if len(chosen) == n - 1: break
    return (cost, chosen) if len(chosen) == n - 1 else (None, chosen)  # None => forest
from collections import deque
# Edmonds-Karp: BFS augmenting paths on an adjacency-matrix residual graph
def max_flow(cap, s, t):                    # cap[u][v] = capacity, modified in place
    n, total = len(cap), 0
    while True:
        par = [-1]*n; par[s] = s; q = deque([s])
        while q and par[t] == -1:
            u = q.popleft()
            for v in range(n):
                if par[v] == -1 and cap[u][v] > 0:
                    par[v] = u; q.append(v)
        if par[t] == -1:                    # no augmenting path -> max flow reached
            return total
        v, bott = t, float('inf')
        while v != s:                       # bottleneck on the path
            bott = min(bott, cap[par[v]][v]); v = par[v]
        v = t
        while v != s:                       # push flow, add residual back-edge
            cap[par[v]][v] -= bott; cap[v][par[v]] += bott; v = par[v]
        total += bott

Where it is used

Interview questions

Common mistakes

Related topics

Graph algorithms: BFS, DFS and shortest paths · Greedy algorithms · Divide and conquer · Dynamic programming · Time and space complexity · DSA interview patterns

Open in the Knowledge reader →Find jobs →