Я не совсем понял после прочтения ответов здесь, поэтому я думал, что я отправлю один из здесь
Общая идея заключается в том, что вы корень дерева в произвольном узле и спрашивает, находится ли этот корень в обложке или нет. Если это так, то вы вычисляете минимальное покрытие вершин поддеревьев, укорененных в его дочерних элементах, путем рекурсии. Если это не так, то каждый дочерний элемент корня должен находиться в покрытии вершин, чтобы охватить все ребра между корнем и его дочерними элементами. В этом случае вы вербуете внуков корня.
Так, например, если у вас было следующее дерево:
A
/ \
B C
/ \ / \
D E F G
Обратите внимание, что при проверке вы знаете, что минимальная вершина покрытия равна {B, C}
. Мы найдем эту минимальную обложку.
Здесь мы начнем с A
.
А в обложке
Мы переходим к двум поддеревам B
и C
и повторяем этот алгоритм. Мы не можем просто заявить, что B
и C
не находятся в обложке, потому что даже если AB
и AC
покрыты, мы не можем ничего сказать о том, нужны ли нам B
и C
быть в обложке или нет.
(Подумайте о следующем дереве, где корень и один из его дочерних элементов находятся в минимальной обложке ({A, D}
)
A
/|\___
B C D
/|\
E F G
)
А не в обложке
Но мы знаем, что AB
и AC
должны быть покрыты, поэтому мы должны добавить B
и C
к обложке. Поскольку B
и C
находятся на обложке, мы можем использовать их детей вместо того, чтобы использовать B
и C
(даже если бы мы это сделали, это не дало бы нам больше информации).
"Формально"
Пусть C(x)
будет размером минимальной обложки с корнем в x
.
Тогда
C(x) = min (
1 + sum ( C(i) for i in x's children ), // root in cover
len(x's children) + sum( C(i) for i in x's grandchildren) // root not in cover
)