Есть ли эффективный способ найти размеры компонентов в графе связующего дерева после удаления ребра?

Моя задача — эффективно обрабатывать Q запросов в графе связующего дерева с N узлами.

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

Моя текущая идея состоит в том, чтобы запустить DFS с двух узлов, соединенных этим краем, убедившись, что DFS никогда не пересекает само ребро. Таким образом, я смогу найти размеры двух компонентов за O(N) времени при общей сложности O(Q * N).

Тем не менее, я думаю, что есть какая-то предварительная обработка, которую я могу сделать, чтобы еще больше снизить временную сложность моего решения, но я просто не могу придумать, что это может быть. Может кто-нибудь указать мне в правильном направлении?


person Anthony Smith    schedule 12.09.2020    source источник


Ответы (1)


Ну, вот стратегия, которую я только что придумал:

Во-первых, найдите любой узел, степень которого точно равна 1 (который гарантированно существует в графе остовного дерева; он называется листом). Запустите DFS с этого узла, сохранив переменную count, представляющую количество посещенных узлов. Каждый раз, когда вы пересекаете ребро, размер двух компонентов, образованных удалением этого ребра, должен быть равен count и N - count из-за особых свойств дерева (в частности, между любой парой узлов существует ровно один путь). Это приводит к алгоритму с O(N) предварительной обработкой и O(1) ответами на запросы с общей временной сложностью O(N + Q).

person Telescope    schedule 12.09.2020
comment
Работает отлично. На самом деле вы можете укоренить дерево где угодно. - person David Eisenstat; 13.09.2020