Найти несколько LCA в некорневом дереве


Я пытаюсь реализовать LCA для некорневого дерева. Я дал дерево (связный неориентированный граф без циклов) и последовательность запросов о LCA для некоторого корня и двух вершин. Каждый конкретный запрос может иметь различный корень, поэтому я не могу использовать алгоритмы, которые предварительно обрабатывают дерево для произвольного корня в начале.

До сих пор я пытался найти пути от обеих вершин до корня с помощью DFS, а затем проверить, где он расходится, но его несколько медленный (O(nq), где q количество запросов).

Есть предложения, как предварительно обработать дерево, чтобы иметь сублинейную сложность запроса?

2 3

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, то ответом является соответствующая вершина.