This can be done in O(n) time, where n is the number of nodes. The solution is recursive:
The minimum cost path for a leaf node is trivial - it is just the node itself, with the node's own cost.
To find the minimum cost path for an internal node, make recursive calls on all its children, and select whichever child node has the lowest cost for its minimum cost path. The cost of the path equals the node's own cost plus the cost of the path for that child.
To recover the path, simply return both the cost and the path from the function. The recursive case has to extend the path with the current node.
The total running time is O(n) because the non-recursive work done for an internal node is proportional to the number of children. The running time cannot be improved on asymptotically, but it could be optimised in practice using a branch-and-bound algorithm which keeps track of the lowest cost path so far, and rejecting paths which exceed it.
Here's an example in Python:
class Node:
def __init__(self, cost, children=()):
self.cost = cost
self.children = children
def __repr__(self):
return 'Node({})'.format(self.cost)
root = Node(1, (
Node(2, (
Node(5, (Node(9),)),
Node(6, (Node(9),)),
Node(9),
)),
Node(3, (
Node(8, (Node(9),)),
Node(9),
)),
Node(4, (Node(9),)),
))
def min_cost_path(node):
if not node.children:
return [node], node.cost
else:
# list of (path, cost) pairs
options = [min_cost_path(c) for c in node.children]
path, cost = min(options, key=lambda option: option[1])
path.append(node)
return path, cost + node.cost
Example:
>>> path, cost = min_cost_path(root)
>>> path
[Node(9), Node(2), Node(1)]
>>> cost
12
Note that the path is returned in reverse order.