Розглянемо спрямований графік на якому можна динамічно додавати ребра та робити певні запити.
Приклад: ліс-роз'єднаний ліс
Розглянемо наступний набір запитів:
arrow(u, v)
equiv(u, v)
find(u)
перший додає стрілку до графа, другий вирішує, чи , останній знаходить канонічний представник класу еквівалентності , тобто такий, що означає .u ↔ ∗ v ↔ ∗ r ( u ) u ↔ ∗ v r ( v ) = r ( u )
Існує відомий алгоритм, що використовує структуру даних лісового набору, що реагує на роз'єднання, реалізуючи ці запити в квазіконстантній амортизованій складності, а саме . Зауважте, що в цьому випадку equiv
реалізується за допомогою find
.
Більш складний варіант
Тепер мене цікавить більш складна проблема, де важливі напрямки:
arrow(u, v)
confl(u, v)
find(u)
Перша додає стрілку , секунди визначає, чи є вузол доступний як і , тобто . Останній повинен повернути об’єкт таким, що означає де повинен бути легко обчислюваний. (Для того, щоб, скажімо, обчислити ). Мета - знайти хорошу структуру даних, щоб ці операції були швидкими.w u v u → ∗ ← ∗ v r ( u ) u → ∗ ← ∗ v r ( u ) ∙ r ( v ) ∙confl
Цикли
Графік може містити цикли.
Я не знаю, чи існує спосіб ефективного та поступового обчислення сильно з’єднаних компонентів, щоб розглянути лише DAG для основної проблеми.
Звичайно, я також вдячний для вирішення проблемних груп. Це відповідало б поступовим обчисленням найменш поширеного предка.
Наївний підхід
Тут не корисна структура лісових даних, що встановлюються на розріз, оскільки вона не враховує напрямок країв. Зауважте, що не може бути одним вузлом, якщо граф не є злитим.
Можна визначити і визначити як коли . Але як обчислити це поступово?∙ S 1 ∙ S 2 S 1 ∩ S 2 ≠ ∅
Ймовірно, що обчислення такого великого набору не корисне, менший набір повинен бути цікавішим, як у звичайному алгоритмі пошуку об'єднання.