Given a graph and a set of terminals, find the minimum-weight connected subgraph containing all terminals. It may use extra (“Steiner”) vertices.
Exact: Dreyfus-Wagner —
DP over subsets of terminals: dp[mask][v] = the minimum cost of a tree connecting the terminal set mask and containing vertex .
Two transitions:
- Merge two sub-trees meeting at : .
- Grow by moving the meeting point along an edge — a Dijkstra over the whole graph for each mask.
See Dreyfus-Wagner for the code. Practical for - with in the thousands.
Approximation
The metric-closure MST — a 2-approximation:
- Compute all-pairs shortest paths among the terminals.
- Build the complete graph on the terminals with those distances.
- Take its MST.
- Expand each MST edge back into its shortest path.
// 2-approximation
for each terminal t: dijkstra(t); // k runs
build complete graph on terminals with dist[i][j]
mst = kruskal(that graph)
expand each MST edge into its pathWhy 2: the optimal Steiner tree, doubled, gives an Eulerian tour of the terminals; shortcutting yields a spanning tree on the terminals of cost , and the MST is no worse. ∎
The best known ratio is (Byrka et al.), via LP rounding.
The variants
| Variant | Complexity |
|---|---|
| shortest path, P | |
| MST, P | |
| General | NP-hard |
| small | FPT: |
| Steiner tree in a tree | P — the answer is the virtual tree of the terminals |
| Steiner forest (pairs to connect) | NP-hard; 2-approximation by primal-dual |
| Directed Steiner tree (arborescence) | much harder; no constant-factor approximation known |
| Euclidean Steiner tree | NP-hard; PTAS exists; Steiner points meet at |
| Rectilinear Steiner tree | NP-hard; VLSI routing |
| Prize-collecting Steiner tree | NP-hard; 2-approximation |
| Node-weighted Steiner tree | -approximable |
Steiner tree in a tree
When the graph is itself a tree, the minimum connected subgraph containing the terminals is simply the union of the paths between them — computable in with a virtual tree:
Equivalently, sort the terminals by DFS entry time and sum around the cycle, halved.
sort(terms.begin(), terms.end(), byTin);
long long total = 0;
for (int i = 0; i < k; i++)
total += dist(terms[i], terms[(i + 1) % k]);
total /= 2;Every edge of the Steiner tree is traversed exactly twice by that cyclic walk — a neat and frequently useful identity.
Where it appears
- Network design — connect a set of sites at minimum cable cost.
- VLSI routing — the rectilinear version.
- Phylogenetics — minimum evolution trees.
- Contest problems — usually with terminals, signalling Dreyfus-Wagner.
The recognition cue
When a problem says “connect these special vertices at minimum cost” and is suspiciously small () while is large, it is a Steiner tree and the intended solution is the DP. That constraint pattern is the giveaway.
See also: Dreyfus-Wagner · Minimum Spanning Tree · Virtual Tree