This can be enabled in linear mode using dynamic programming.
A connected graph with N vertices and N edges contains exactly one cycle. Start by discovering this cycle (using depth search).
Then remove any edge in this loop. Two vertices incident to this edge, u and v . After this edge removal we have a tree. Interpret it as a root tree with root u .
The repetition of dynamic programming for this tree can be defined as follows:
- w 0 [k] = 0 (for leaf nodes)
- w 1 [k] = vertex_cost (for leaf nodes)
- w 0 [k] = w 1 [k + 1] (for nodes with one descendant)
- w 1 [k] = vertex_cost + min ( w 0 [k + 1], w 1 [k + 1]) (for nodes with one descendant)
- w 0 [k] = sum ( w 1 [k + 1], x 1 [k + 1], ...) (for branch nodes)
- w 1 [k] = vertex_cost + sum (min ( w 0 [k + 1], w 1 [k + 1]), min ( x 0 [k + 1], x 1 [k + 1]), .. .)
Here k is the depth of the node (distance from the root), w 0 is the cost of the subtree, starting with node w when w is not in the “subset”, w 1 is the cost of the subtree, starting with node w , when w is in the “subset” "
For each node, only two values must be calculated: w 0 and w 1 . But for the nodes that were in the loop, we need 4 values: w i, j , where i = 0 if node v is not in the “subset”, i = 1 if node v is in the “subset”, j = 0 if the current node is not in the "subset", j = 1 if the current node is in the "subset".
The optimal cost of a "subset" is defined as min ( u 0,1 , u 1,0 , u 1,1 ). To get a "subset", save the back pointers along with each value of the tree tree and use them to restore the subset.
Evgeny Kluev
source share