Найти несколько LCA в некорневом дереве
Я пытаюсь реализовать LCA для некорневого дерева. Я дал дерево (связный неориентированный граф без циклов) и последовательность запросов о LCA для некоторого корня и двух вершин. Каждый конкретный запрос может иметь различный корень, поэтому я не могу использовать алгоритмы, которые предварительно обрабатывают дерево для произвольного корня в начале.
До сих пор я пытался найти пути от обеих вершин до корня с помощью DFS, а затем проверить, где он расходится, но его несколько медленный (O(nq), где q количество запросов).
Есть предложения, как предварительно обработать дерево, чтобы иметь сублинейную сложность запроса?
2 ответа:
Пусть LCA (u, v, w) - LCA из v и w относительно корня u. чтобы вычислить LCA (u, v, w), мы можем вычислить для любого фиксированного r,
LCA(r, u, v) LCA(r, u, w) LCA(r, v, w)
И возьмем "нечетного человека", то есть, если два равны, а третий отличается, то возьмем третьего, иначе они все равны, поэтому возьмем этот узел.
Возьмите произвольную вершину в качестве корня и предварительно обработайте дерево для LCA. Для каждого запроса (u,v) и r в качестве корня пусть w-LCA u и v в дереве.
- Если w находится в поддереве r, то W-ответ.
- Если r находится в поддереве w, то R-ответ.
- Если r находится в поддереве u или v, то ответом является соответствующая вершина.