Consider a directed graph $G$ on which one can dynamically add edges and make some specific queries.
Example: disjoint-set forest
Consider the following set of queries:
arrow(u, v)
equiv(u, v)
find(u)
the first one adds an arrow $u→v$ to the graph, the second one decides if $u↔^*v$, the last one finds a canonical representative of the equivalence class of $↔^*$, i.e. a $r(u)$ such that $u↔^*v$ implies $r(v)=r(u)$.
There is a well-known algorithm using the disjoint-set forest data structure implementing these queries in quasi-constant amortized complexity, namely $O(α(n))$. Note that in this case equiv
is implemented using find
.
More complex variant
Now I'm interested in a more complex problem where the directions do matter:
arrow(u, v)
confl(u, v)
find(u)
the first adds an arrow $u→v$, the seconds decides if there is a node $w$ reachable from both $u$ and $v$, i.e. $u→^*←^*v$. The last one should return an object $r(u)$ such that $u→^*←^*v$ implies $r(u) \bullet r(v)$ where $\bullet$ should be easily computable. (In order to, say, computes confl
). The goal is to find a good data structure such that these operations are fast.
Cycles
The graph can contain cycles.
I don't know if there is a way to efficiently and incrementally compute the strongly connected components, in order to only consider DAGs for the main problem.
Of course I would appreciate a solution for DAGs, too. It would correspond to an incremental computation of the least common ancestor.
Naive approach
The disjoint-set forest data structure is not helpful here, since it disregards the direction of the edges. Note that $r(u)$ cannot be a single node, in the case the graph is not confluent.
One can define $r(u)=\{v ∣ u→^*v\}$ and to define $\bullet$ as $S_1\bullet S_2$ when $S_1 ∩ S_2≠∅$. But how to compute this incrementally?
Probably that computing such a big set is not useful, a smaller set should be more interesting, as in the usual union-find algorithm.