Considere um gráfico direcionado no qual é possível adicionar dinamicamente arestas e fazer algumas consultas específicas.
Exemplo: floresta com conjunto separado
Considere o seguinte conjunto de consultas:
arrow(u, v)
equiv(u, v)
find(u)
o primeiro adiciona uma seta para o gráfico, o segundo decide se , o último se encontra um representante canônico da classe de equivalência de , ou seja, um de tal forma que implica .
Existe um algoritmo bem conhecido usando a estrutura de dados da floresta de conjunto separado, implementando essas consultas com complexidade amortizada quase constante, a saber . Observe que, neste caso, é implementado usando .equiv
find
Variante mais complexa
Agora, estou interessado em um problema mais complexo, onde as instruções são importantes:
arrow(u, v)
confl(u, v)
find(u)
o primeiro adiciona uma seta , os segundos decide se existe um nó acessível a partir do e , ou seja, . O último deve retornar um objeto forma que implique onde deva ser facilmente computável. (Para, digamos, computar ). O objetivo é encontrar uma boa estrutura de dados para que essas operações sejam rápidas.w u v u → ∗ ← ∗ v r ( u ) u → ∗ ← ∗ v r ( u ) ∙ r ( v ) ∙confl
Ciclos
O gráfico pode conter ciclos.
Não sei se existe uma maneira de calcular de maneira eficiente e incremental os componentes fortemente conectados, a fim de considerar apenas os DAGs para o problema principal.
É claro que eu também apreciaria uma solução para DAGs. Corresponderia a uma computação incremental do ancestral menos comum.
Abordagem ingênua
A estrutura de dados da floresta desarticulada não é útil aqui, pois desconsidera a direção das arestas. Observe que não pode ser um nó único, caso o gráfico não seja confluente.
Pode-se definir e definir como quando S 1 ∩ S 2 ≠ ∅ . Mas como calcular isso de forma incremental?∙ S 1 ∙ S 2
Provavelmente que a computação de um conjunto tão grande não seja útil, um conjunto menor deve ser mais interessante, como no algoritmo usual de busca por união.