[#sec:lengauer-tarjan]
= Lengauer-Tarjan Dominator Tree Algorithm

Builds the dominator tree for a directed graph using the Lengauer-Tarjan algorithm.

*Complexity:* _O((V+E)log(V+E))_ +
*Defined in:* `<boost/graph/dominator_tree.hpp>`

== Example

[source,cpp]
----
include::example$algorithms/utility/lengauer_tarjan.cpp[]
----

[,text]
----
include::example$algorithms/utility/lengauer_tarjan.txt[]
----

'''

=== (1) Simple version

The simplest version: data structures for depth first search are created internally, and depth first search runs internally.

[source,cpp]
----
template <class Graph, class DomTreePredMap>
void lengauer_tarjan_dominator_tree(
    const Graph& g,
    const typename graph_traits<Graph>::vertex_descriptor& entry,
    DomTreePredMap domTreePredMap);
----

[cols="1,2,5"]
|===
| Direction | Parameter | Description

| IN
| `const Graph& g`
| The graph object on which the algorithm will be applied.
  The type `Graph` must be a model of
  xref:concepts/VertexListGraph.adoc[Vertex List Graph]
  and xref:concepts/BidirectionalGraph.adoc[Bidirectional Graph].

| IN
| `vertex_descriptor entry`
| The entry vertex. The dominator tree will be rooted at this vertex.

| OUT
| `DomTreePredMap domTreePredMap`
| The dominator tree where parents are each children's immediate dominator.

|===

'''

=== (2) Version providing DFS data structures

After calling this function, the user can reuse the depth first search related information filled in property maps.

[source,cpp]
----
template <class Graph, class IndexMap, class TimeMap, class PredMap,
          class VertexVector, class DomTreePredMap>
void lengauer_tarjan_dominator_tree(
    const Graph& g,
    const typename graph_traits<Graph>::vertex_descriptor& entry,
    const IndexMap& indexMap,
    TimeMap dfnumMap, PredMap parentMap, VertexVector& verticesByDFNum,
    DomTreePredMap domTreePredMap);
----

[cols="1,2,5"]
|===
| Direction | Parameter | Description

| IN
| `const Graph& g`
| The graph object on which the algorithm will be applied.
  The type `Graph` must be a model of
  xref:concepts/VertexListGraph.adoc[Vertex List Graph]
  and xref:concepts/BidirectionalGraph.adoc[Bidirectional Graph].

| IN
| `vertex_descriptor entry`
| The entry vertex. The dominator tree will be rooted at this vertex.

| IN
| `IndexMap indexMap`
| This maps each vertex to an integer in the range `[0, num_vertices(g))`.
  The type `VertexIndexMap` must be a model of
  link:../../property_map/doc/ReadablePropertyMap.html[Readable Property Map].
  The value type of the map must be an integer type. The vertex descriptor
  type of the graph needs to be usable as the key type of the map.

| IN/OUT
| `TimeMap dfnumMap`
| The sequence number of depth first search. The type `TimeMap` must be a
  model of
  link:../../property_map/doc/ReadWritePropertyMap.html[Read/Write Property Map].
  The vertex descriptor type of the graph needs to be usable as the key
  type of the `TimeMap`.

| IN/OUT
| `PredMap parentMap`
| The predecessor map records the parent of the depth first search tree.
  The `PredMap` type must be a
  link:../../property_map/doc/ReadWritePropertyMap.html[Read/Write Property Map]
  whose key and value types are the same as the vertex descriptor type of
  the graph.

| IN/OUT
| `VertexVector verticesByDFNum`
| The vector containing vertices in depth first search order. If we access
  this vector sequentially, it's equivalent to access vertices by depth
  first search order.

| OUT
| `DomTreePredMap domTreePredMap`
| The dominator tree where parents are each children's immediate dominator.

|===

'''

=== (3) Version without depth first search

The caller should provide depth first search related information evaluated before calling this function.

[source,cpp]
----
template <class Graph, class IndexMap, class TimeMap, class PredMap,
          class VertexVector, class DomTreePredMap>
void lengauer_tarjan_dominator_tree_without_dfs(
    const Graph& g,
    const typename graph_traits<Graph>::vertex_descriptor& entry,
    const IndexMap& indexMap,
    TimeMap dfnumMap, PredMap parentMap, VertexVector& verticesByDFNum,
    DomTreePredMap domTreePredMap);
----

[cols="1,2,5"]
|===
| Direction | Parameter | Description

| IN
| `const Graph& g`
| The graph object on which the algorithm will be applied.
  The type `Graph` must be a model of
  xref:concepts/VertexListGraph.adoc[Vertex List Graph]
  and xref:concepts/BidirectionalGraph.adoc[Bidirectional Graph].

| IN
| `vertex_descriptor entry`
| The entry vertex. The dominator tree will be rooted at this vertex.

| IN
| `IndexMap indexMap`
| This maps each vertex to an integer in the range `[0, num_vertices(g))`.
  The type `VertexIndexMap` must be a model of
  link:../../property_map/doc/ReadablePropertyMap.html[Readable Property Map].
  The value type of the map must be an integer type. The vertex descriptor
  type of the graph needs to be usable as the key type of the map.

| IN/OUT
| `TimeMap dfnumMap`
| The sequence number of depth first search. The type `TimeMap` must be a
  model of
  link:../../property_map/doc/ReadWritePropertyMap.html[Read/Write Property Map].
  The vertex descriptor type of the graph needs to be usable as the key
  type of the `TimeMap`.

| IN/OUT
| `PredMap parentMap`
| The predecessor map records the parent of the depth first search tree.
  The `PredMap` type must be a
  link:../../property_map/doc/ReadWritePropertyMap.html[Read/Write Property Map]
  whose key and value types are the same as the vertex descriptor type of
  the graph.

| IN/OUT
| `VertexVector verticesByDFNum`
| The vector containing vertices in depth first search order. If we access
  this vector sequentially, it's equivalent to access vertices by depth
  first search order.

| OUT
| `DomTreePredMap domTreePredMap`
| The dominator tree where parents are each children's immediate dominator.

|===

== Description

This algorithm [xref:about/bibliography.adoc#lengauer-tarjan79[59],xref:about/bibliography.adoc#muchnick97[60],xref:about/bibliography.adoc#appel98[61]]
builds the https://en.wikipedia.org/wiki/Dominator_(graph_theory)[dominator tree]
for a directed graph. There are three options
for dealing with the depth first search related values. The simplest version
creates data structures and runs depth first search internally. However,
chances are that a user wants to reuse the depth first search data, so
we have two additional versions.

A vertex _u_ dominates a vertex _v_, if every path of the directed graph
from the entry to _v_ must go through _u_. In the left graph of
<<fig:dominator-tree-example,Figure 1>>, vertex 1 dominates vertex 2,
3, 4, 5, 6 and 7, because we have to pass vertex 1 to reach those
vertices. Note that vertex 4 dominates vertex 6, even though vertex 4 is a
successor of vertex 6. Dominator relationship is useful in many
applications especially for compiler optimization. We can define the
immediate dominator for each vertex such that _idom(n) dominates n_ but
does not dominate any other dominator of _n_. For example, vertex 1, 3
and 4 are dominators of vertex 6, but vertex 4 is the immediate
dominator, because vertex 1 and 3 dominate vertex 4. If we make every
idom of each vertex as its parent, we can build the dominator tree like
the right part of <<fig:dominator-tree-example,Figure 1>>.

[#fig:dominator-tree-example]
.*Figure 1:* An example graph and its dominator tree.
[cols=",,",]
|===
|image:figs/dominator-tree1.gif[figs/dominator-tree1] |
|image:figs/dominator-tree2.gif[figs/dominator-tree2]
|===

An easy way to build a dominator tree is to use an iterative bit vector
algorithm, but it may be slow in the worst case. We implemented the
Lengauer-Tarjan algorithm whose time complexity is
_O((V+E)log(V+E))_.

Lengauer-Tarjan algorithm utilizes two techniques. The first one is, as
an intermediate step, finding the semidominator which is relatively easier
to evaluate than the immediate dominator, and the second one is path
compression. For the detail of the algorithm, see
[xref:about/bibliography.adoc#lengauer-tarjan79[59]].

== Notes

The original HTML documentation contained a double parenthesis typo in the
`lengauer_tarjan_dominator_tree_without_dfs` signature. This has been
corrected to match the actual header file declaration.
