Branching on an Uncovered Edge
A vertex cover is a set of vertices that meets every edge. The decision question is whether a graph has a vertex cover of size at most a specified nonnegative integer \(k\). A useful recursive strategy is to select an uncovered edge \(uv\). Any vertex cover must contain \(u\), \(v\), or both, so the algorithm can explore two cases: include \(u\), or include \(v\). Each choice uses one unit of the available budget.
All graphs in this tutorial are finite and simple. For a graph \(G=(V,E)\), a vertex cover is a set \(C\subseteq V\) such that every edge has at least one endpoint in \(C\). A cover is not required to be minimum unless that is stated. The algorithm decides whether there is a cover \(C\) with \(|C|\le k\); it does not need to list every such cover.
In an implementation, each successful sequence of choices gives a cover: add each chosen endpoint to the selected set. Deleting that endpoint from the residual graph removes exactly the edges it covers. If the recursion reaches an edgeless residual graph without exceeding the budget, the selected vertices cover every original edge. It is important to test for a negative budget before accepting an edgeless graph: a sequence that has already selected \(k+1\) vertices is not a cover of size at most \(k\), even if its last choice happened to cover the final edge.
If \(b<0\), return “no.”
If \(E(H)=\varnothing\) and \(b\ge0\), return “yes.” The vertices selected on the route to this call form a cover.
Choose any \(uv\in E(H)\). Make one call that includes \(u\) and one that includes \(v\), reducing the budget by one in both calls.
The order of the two branches does not affect whether the answer is correct. Choosing an edge is essential: branching on an arbitrary vertex without a reason that every valid cover must include it could omit valid covers from the search.
Why the Recursion Is Correct
Proof. We prove the claim by induction on \(|V(H)|+|E(H)|+\max(b,0)\), using the algorithm's recursive definition. If \(b<0\), no set has size at most \(b\), so returning “no” is correct. Suppose \(b\ge0\). If \(E(H)=\varnothing\), the empty set is a vertex cover of size \(0\le b\), so returning “yes” is correct.
Now suppose \(b\ge0\) and \(H\) has an edge \(uv\). If either recursive call returns “yes,” then, by the induction hypothesis, the corresponding smaller graph has a cover \(D\) of size at most \(b-1\). In the call on \(H-u\), the set \(D\cup\{u\}\) covers \(H\): every edge incident with \(u\) is covered by \(u\), and all other edges are present in \(H-u\) and covered by \(D\). Its size is at most \((b-1)+1=b\). The same argument applies to the call on \(H-v\). Thus a “yes” from either branch implies that \(H\) has a cover of size at most \(b\).
Conversely, suppose \(H\) has a cover \(C\) with \(|C|\le b\). Since \(uv\) is an edge, \(C\) contains \(u\) or \(v\). If \(u\in C\), then \(C\setminus\{u\}\) covers \(H-u\) and has size at most \(b-1\), so the induction hypothesis makes the \(u\)-branch return “yes.” If \(u\notin C\), then \(v\in C\); deleting \(v\) from \(C\) gives a cover of \(H-v\) of size at most \(b-1\), so the \(v\)-branch returns “yes.” Hence the algorithm returns “yes” whenever such a cover exists, proving both directions. \(\square\)
The induction applies to the recursive calls because deleting a vertex strictly reduces the number of vertices, and the budget also falls by one. In particular, every nonterminal call has smaller induction measure than its parent.
Worked Example: A Path with Budget Two
Let \(G=(V,E)\) have \(V=\{1,2,3,4\}\) and \(E=\{12,23,34\}\), and test whether \(G\) has a vertex cover of size at most \(k=2\). Choose the middle edge \(23\) first. The table follows the branch that selects \(2\), then \(3\).
| Call | Selected vertices | Residual edges | Budget | Action |
|---|---|---|---|---|
| Root | \(\varnothing\) | \(\{12,23,34\}\) | 2 | Branch on \(23\) |
| 1 | \(\{2\}\) | \(\{34\}\) | 1 | Branch on \(34\) |
| 1a | \(\{2,3\}\) | \(\varnothing\) | 0 | Accept |
The other child of call 1 selects \(4\), leaving the residual edge \(34\) covered as well; its selected set is \(\{2,4\}\), and it also accepts with budget \(0\). The root's other child selects \(3\), leaving edge \(12\); selecting \(1\) or \(2\) covers that edge within the remaining budget \(1\). Thus the stated branch already supplies a cover, \(\{2,3\}\).
Check: edge \(12\) meets \(2\), edge \(23\) meets both selected vertices, and edge \(34\) meets \(3\). So \(\{2,3\}\) is a cover of size \(2\). Also, edges \(12\) and \(34\) are disjoint, so any cover must use at least one endpoint of each and therefore has size at least \(2\). This independently verifies that the cover found is minimum.
Worked Example: A Triangle with Budget One
Let \(G=(V,E)\) have \(V=\{1,2,3\}\) and \(E=\{12,23,13\}\), and test \(k=1\). Branch on edge \(12\). If the first call selects \(1\), the residual graph has the edge \(23\) and budget \(0\). Branching on \(23\) selects either \(2\) or \(3\); each resulting call has budget \(-1\), so both return “no.”
If instead the root call selects \(2\), the residual edge is \(13\) and the budget is \(0\). Its two children select \(1\) or \(3\), each reaching budget \(-1\), and both return “no.” Therefore the root returns “no.” The full search has one call at depth \(0\), two at depth \(1\), and four at depth \(2\), for \(1+2+4=7\) calls. The four calls at depth \(2\) have negative budget and are still part of the search tree.
Check: a one-vertex set cannot cover all three edges: selecting vertex \(1\) leaves \(23\), selecting \(2\) leaves \(13\), and selecting \(3\) leaves \(12\). Thus no cover of size at most \(1\) exists, in agreement with the algorithm.
Bounding the Search Tree
Represent the recursion as a rooted tree of calls. Every call that branches has at most two children. If a call is at depth \(d\), where the root is at depth \(0\), its budget is \(k-d\): each step from parent to child has selected exactly one additional vertex and reduced the budget by one. A call at depth \(k+1\) has budget \(-1\), so it returns “no” without branching. A call at depth \(k\) has budget \(0\), but it may still have an uncovered edge and branch, creating calls at depth \(k+1\).
Proof. A call can branch only at depths \(0,1,\ldots,k\). Therefore the tree has height at most \(k+1\), since children of calls at depth \(k\) are at depth \(k+1\) and cannot branch. At depth \(i\), a binary tree has at most \(2^i\) calls. Summing this bound from depth \(0\) through depth \(k+1\) gives at most \(\sum_{i=0}^{k+1}2^i=2^{k+2}-1\) calls. A binary tree of height at most \(k+1\) has at most \(2^{k+1}\) leaves: extending any early-ending leaf down to depth \(k+1\) assigns it a distinct descendant position among the at most \(2^{k+1}\) positions at that depth. Thus the leaf bound also holds.
For the running time, a direct implementation can find an uncovered edge, construct the two smaller residual graphs and maintain the selected vertices using \(O(n+m)\) work per call. Multiplying by the call bound gives \(O((2^{k+2}-1)(n+m))\), which is \(O(2^k(n+m))\), since \(2^{k+2}=4\cdot2^k\). This is a bound on the decision algorithm; it does not assert that every input reaches the maximum-sized tree. \(\square\)
The depth-\(k+1\) calls matter even though none of them branches. For \(k=0\) and a graph consisting of one edge, the root branches into two calls with budget \(-1\). There are two leaves and three calls altogether. The general bounds give \(2^{0+1}=2\) leaves and \(2^{0+2}-1=3\) calls, matching this example.
Worked Traces and Practical Interpretation
Worked Example: Disconnected Edges and an Isolated Vertex
Let \(G=(V,E)\) have \(V=\{a,b,c,d,e,f\}\) and \(E=\{ab,bc,de\}\). Vertex \(f\) is isolated. Test \(k=2\), and choose \(ab\) at the root. The branch selecting \(a\) leaves edges \(bc\) and \(de\), with budget \(1\). If that call selects \(b\), edge \(de\) remains with budget \(0\), and either endpoint choice creates a call with budget \(-1\). If it selects \(c\), edge \(de\) likewise remains with budget \(0\), and either endpoint choice is over budget. So the branch selecting \(a\) fails.
The branch selecting \(b\) leaves only edge \(de\), with budget \(1\). Selecting \(d\) leaves no edges with budget \(0\), so this call accepts and returns the cover \(\{b,d\}\). Selecting \(e\) also accepts and returns \(\{b,e\}\). The isolated vertex \(f\) never lies on an edge and need not be selected.
Check: \(\{b,d\}\) covers \(ab\) and \(bc\) through \(b\), and covers \(de\) through \(d\). Edges \(ab\) and \(de\) are disjoint, so a cover needs at least two vertices. Thus the returned cover has minimum possible size, namely \(2\).
The branch-and-bound argument is useful when the budget \(k\) is the parameter of interest. The graph may be large, but the search has at most \(2^{k+2}-1\) calls, multiplied by the work per call. In particular, for fixed \(k\), the direct running-time bound grows linearly with \(n+m\). This bound does not make the method practical for every large \(k\), because the exponential factor increases with the budget.
The earlier material on matching lower bounds gives a quick optional rejection test: if a graph contains more than \(k\) pairwise disjoint edges, no cover of size at most \(k\) can exist, since each of those edges requires a distinct selected endpoint. Such a test can be applied before branching, but it is not needed for the correctness or the stated worst-case bound of the basic algorithm.
Common Pitfall: Counting Only Through Depth \(k\)
A frequent counting error is to include calls only at depths \(0\) through \(k\), obtaining \(2^{k+1}-1\) calls and \(2^k\) leaves. This omits children created by calls at depth \(k\). Those children are at depth \(k+1\), have negative budget, and are terminal calls—but they still count. For \(k=0\) with one edge, the incorrect calculation would predict \(1\) call and \(1\) leaf, while the actual recursion makes the root call and two negative-budget children: \(3\) calls and \(2\) leaves. Summing through depth \(k+1\) gives the correct general bounds \(2^{k+2}-1\) calls and \(2^{k+1}\) leaves. The asymptotic running-time conclusion remains \(O(2^k(n+m))\); the exact count, however, must include those final calls.
Check Your Understanding
Use the recursive state and the search-tree bounds to answer the following questions.
- For a graph with one edge and budget \(k=1\), what are the budgets at depths \(0\), \(1\) and \(2\), and at which depths can branching occur?
- Run the algorithm on \(V=\{1,2,3,4\}\), \(E=\{12,23,34\}\), with budget \(1\). Does it accept? Explain by tracing the branches on edge \(23\).
- Explain why choosing either endpoint of an uncovered edge preserves completeness: why can no cover be missed by considering the two branches?
- For \(k=2\), calculate the stated upper bounds on total calls and leaves by summing the levels of the search tree.
- Why must a call with negative budget return “no” even if its residual graph is edgeless?