Topological Decomposition of Directed Graphs

The analysis of directed graphs is important in application areas like software engineering, bioinformatics, or project management. Distin-guishing between topological structures such as cyclic and hierarchical subgraphs provides the analyst with important information. However, until now, graph drawing algorithms draw the complete directed graph either hierarchically or cyclic. Therefore, we introduced new algorithms for decomposing the input graph into cyclic subgraphs, directed acyclic subgraphs, and tree subgraphs. For all of these subgraphs, optimized lay-out algorithms exist. We developed and presented a new algorithm for drawing the complete graph based on the decomposition using and combining these layouts. In this paper, we focus on the algorithms for the topological decomposition. We describe them on an intermediate level complementing the previous descriptions on the high and the low level. Besides the motivation, illustrative examples of all cases that need to be considered by the algorithm, standard as well as more complex ones, are given. We complement this description by a complexity analysis of all algorithms.


Introduction
Directed graphs are used for displaying relations between entities where the direction of the relation is important.An example from software engineering are call graphs.If method or function A calls method or function B, then the reverse relation-B calls A-does not necessarily hold.Besides software engineering there are several other application areas and applications where directed graphs are regularly used, like metabolic networks in biology and bioinformatics, or PERT charts for project management [8].In the handbook of graph drawing [8], directed graphs are discussed in Chapter 13, "Hierarchical Drawing Algorithms".
Frequently, the Sugiyama algorithm [7] is used for drawing directed graphs, even though its main purpose is the drawing of directed acyclic graphs.Only recently, Bachmaier et al. [3,4] proposed a cyclic layout to draw directed graphs containing cycles.These publications address the complete layout and the coordinate assignment phase and use the leveling phase described before [5].The disadvantages of both layouts become obvious, when analyzing directed graphs.In a Sugiyama layout, cycles are difficult to detect, while in the cyclic layout, non-cyclic parts are not obvious.On the other hand, distinguishing between cyclic and non-cyclic sub-graphs of a directed graph are important in the applications areas.For example, cyclic dependencies of classes in an object-oriented model may reduce modularity.
Decomposing directed graphs into cyclic and non-cyclic sub-graphs as well as drawing these subgraphs such that the respective structure is easily recognizable enables a more efficient and effective analysis of the relations represented by the graphs.Hence, Abuthawabeh and Zeckzer [1,2] presented their topological layout approach for directed graphs.First, the graph is decomposed into nontrivial cyclic subgraphs, trees, and DAGs.Then, each of the components is drawn using the most adequate layout: Bachmaier's algorithm for non-trivial cyclic subgraphs [3,4] the Sugiyama layout for DAGs [7], and the tree layout proposed by Walker [9] and improved by Buchheim et al. [6].
Previously, the topological approach was described on a high level [2] and on a low level [1].In this paper, it will be described on an intermediate level focusing on the topological decomposition only.For the topological decomposition much more details and examples are provided compared to the high level description [2], while the implementation details of the low level description [1] were omitted for clarity.

Motivation and Definitions
Let G = (V, E) be a directed graph where V denotes a set of vertices and E denotes a set of directed edges.Until recently [8], the standard way of drawing such a graph was using the Sugiyama algorithm [7].However, this algorithm was intended to be applied to acyclic directed graphs only [7].Nevertheless, it was also used for cyclic directed graphs by first reversing enough edges to make the graph acyclic, second layouting the acyclic graph, and finally, putting the original edges instead of the reversed ones thus obtaining the final drawing.While this keeps the layered part of the graphs, cycles are difficult to spot.We call this the hierarchical approach.
Recently, Bachmaier et al. [3,4] proposed a cyclic layout for directed graphs.In this case, all cycles are clearly depicted and can readily be analyzed.However, also all layered, acyclic parts are drawn in a cyclic way, making it difficult to spot them.We call this the cyclic approach.
Therefore, Abuthawabeh and Zeckzer [1,2] presented their topological layout approach for directed graph that decomposes the graph into non-trivial cyclic subgraphs (ntCS), directed acyclic graphs (DAGs), and trees.Then, each of the components is drawn using the best currently available algorithm: Bachmaier's algorithm for non-trivial cyclic subgraphs [3,4], Sugiyama's algorithm for DAGs [7], and the improved Walker's algorithm for trees [6].We call this the topological approach, because each subgraph type has a certain topology.
The goal of this paper is to give more details on the decomposition of directed graphs than in our previous publication [2].One of the most important concepts of our approach is the distinction between trivial cycle and non-trivial cycle.In Figure 1(a), two strongly-connected components G1 and G2 are shown.In G1, there are two cycles between two nodes, each.G1 does not really need to be drawn in a cyclic way, as the two-node cycle will be clear in both approaches, hierarchical and cyclic.G2, however, contains as well two-node cycles as threenode cycles.In this case, the cycle can be detected best if the graph is drawn using the cyclic approach.This leads to the following definitions.With these definitions, we can now define non-trivial cyclic subgraphs (ntCS).Starting from G1 and G2, we can extract all subgraphs that do not contain trivial cycles.This can be achieved by removing one of the edges of each trivial cycle.In all these cases, we consider the removed edge to be the back edge.Doing so, we find that for G1 this results in weakly-connected components only.Figure 1(b) shows all extractable subgraphs of G1.
Doing so for G2, however, results in either strongly-connected components (Figure 1(c)) or weakly-connected components (Figure 1(d)).By construction, none of the subgraphs of G2 contains trivial cycles.This motivates the following definition.

Definition 2.7 (Non-Trivial Cyclic Subgraph)
A non-trivial cyclic subgraph (ntCS) is a strongly-connected component G = (V, E) that contains at least one strongly-connected component G = (V , E ), V = V , and E ⊆ E without trivial cycles.
Remark 2.8 In Definition 2.7, the strongly connected component G might contain several different strongly-connected components without trivial cycles.Remark 2.9 In Definition 2.7, E does not contain back edges.

JGAA, 21(4) 589-630 (2017) 593
In the remainder of this paper, we will show how to decompose a directed graph into ntCSs, DAGs, and trees by removing back edges and thereby trivial cycles.For this, we extend the conventional definitions of tree and DAG.Definition 2.10 (Trivial Down-Tree) A trivial down-tree is a tree that does not contain trivial cycles and whose root node has in-degree zero.
Definition 2.11 (Trivial Up-Tree) A trivial up-tree is a tree that does not contain trivial cycles and whose root node has out-degree zero.Definition 2.12 (Trivial DAG) A trivial DAG is a DAG that does not contain trivial cycles.

Definition 2.13 (Non-Trivial Down-Tree)
A non-trivial down-tree is a wCC that contains trivial cycles and that can be transformed into a trivial downtree by removing one edge of each double edge.Definition 2.14 (Non-Trivial Up-Tree) A non-trivial up-tree is a wCC that contains trivial cycles and that can be transformed into a trivial up-tree by removing one edge of each double edge.Definition 2.15 (Non-Trivial DAG) A non-trivial DAG is a wCC that contains trivial cycles and that can be transformed into a DAG by removing one edge of each double edge.Definition 2.16 (Down-Tree) A down-tree is either a trivial or a non-trivial down-tree.Definition 2.17 (Up-Tree) An up-tree is either a trivial or a non-trivial uptree.
Definition 2.18 (DAG) A DAG is either a trivial or a non-trivial DAG.
Remark 2.20 A wCC without ntCS that contains trivial cycles might be a nontrivial DAG, a non-trivial down-tree, and a non-trivial up-tree at the same time, depending on which back-edges are removed.

Decomposing Directed Graphs
In our approach, directed graphs are decomposed as follows.Given a directed graph G, first all its weakly connected components (wCCs) are extracted.Each of these wCCs is then decomposed into ntCSs, DAGs, and trees.Figure 2 shows an overview of this decomposition [1].It starts by detecting ntCSs in each wCC (Section 4).After removing the edges of all ntCSs found in the wCCs, it splits the remaining wCCs at the ntCSs into smaller wCCs (Section 5).Finally, the  resulting wCCs are classified as down-trees, up-trees, and DAGs (Section 6).Please notice, that these trees and DAGs might contain trivial cycles [1,2].
In this paper, we focus on the special cases that need to be considered.Compared to our previous paper [2], much more detail is provided.On the other hand, the implementation details are described by Abuthawabeh in his PhD thesis [1].

Overview
The first step of the topological decomposition process of a directed graph is detecting all non-trivial cyclic subgraphs (ntCSs).The detection of all ntCSs follows all edges.No edge will be revisited twice during this search.
This step can logically be decomposed into two sub-steps.First, a wCC component is randomly selected.
The first sub-step recursively constructs paths through this wCC starting at a node and applying depth first search (Section 4.2).The second sub-step is responsible for checking if a part of this path is a (partial) ntCS (Section 4.3).If a ntCS is found, it is added to the set of ntCSs.If necessary, ntCSs are merged.After handling all nodes and edges of the current wCC, the next untreated wCC is randomly selected and the two sub-steps are repeated.After all wCCs have been checked for ntCSs, this step is finished.
Figures 3-9 show examples illustrating in detail all potential situations that might occur during ntCSs detection.They will be described in the respective parts of the ntCS detection algorithm.All relevant algorithms are listed in Appendix A, Algorithms 1-5.

Constructing Paths and Handling Back Edges
To find all ntCSs of a wCC (F ind ntCS in wCC, Algorithm 1), a node is randomly selected from the wCC and a path (pathN odes) through the wCC is created following outgoing edges only using depth first search (F ind ntCS, Algorithm 2 and F ind ntCS Rec, Algorithm 3).While creating the path, it is checked if a part of the path forms a ntCS.All ntCS found during path creation are stored in a list (ntCSs).All nodes and edges found during path creation are marked.If there are unvisited nodes and edges of the wCC after the path creation for the current starting node (backtracking), a new path is created starting at a randomly selected unmarked node and the search is repeated.
The ntCS detection algorithm F ind ntCS (Algorithm 2) performs the following steps: 1. Increment the incomingEdgeCounter of the last node of the path stored in pathN odes (line 1) 2. If the last node of the path was already visited, check if this creates a ntCS (lines 2-3).
3. Otherwise, mark the last node of the path as visited (line 4-5).
4. Follow all outgoing edges of the last node of the path (line 7-30).
While following all outgoing edges, F ind ntCS Rec is called.It takes care of the recursive call of F ind ntCS (line 4) storing the outgoing edge in the edges path (line 3) and the target node of the outgoing edge in the nodes path (line 2).Both will be deleted from their respective paths directly after invoking F ind ntCS (backtracking, lines 5-6).Moreover, the outgoing edge is marked as being visited (line 1).This flag will not be removed.As this code is needed two times by F ind ntCS (lines 16 and 26), calling F ind ntCS Rec instead avoids duplicated code.The first step of F ind ntCS, incrementing the counter of incoming edges, is needed by its fourth step and explained there.For the first node of the path, this step is not needed.However, this case is not checked as it has no influence on the algorithm.
Marking the last node of the path (lastN ode, step 3) is needed for two reasons.First of all, an already marked node will be checked for finding ntCSs (step 2).Second, already marked nodes will not be considered as starting points for further paths by F ind ntCS.
In the following, steps 2 and 4 of the algorithm will be explained by describing two cases: (1) wCCs without trivial cycles (Figure 3) and (2) wCCs with trivial cycles (Figure 4).Only relevant steps will be described.
The example in Figure 3 shows the standard case of detecting a single ntCS in a wCC without trivial cycles (no back edges).Starting at node 0, a path of nodes containing node 0 and an empty path of edges are created.F ind ntCS marks node 0 as visited (line 5), traverses the outgoing edge 0 → 1 (lines 8, 9, 14-16), adds node 1 and edge 0 → 1 to the corresponding data structures (F ind ntCS Rec), and marks the edge as visited (F ind ntCS Rec).Then, it marks node 1 as being visited, follows edge 1 → 2, marks node 2 as being visited, and follows edge 2 → 0, updating the respective data structures.Now, the nodes path is (0, 1, 2, 0), the edges path contains the edges {e1, e2, e3}, and lastN ode = 0. Further, all nodes are marked as being visited.The next call to F ind ntCS finds that lastN ode is marked visited (line 2) and therefore (line 3) calls Check ntCS (Algorithm 4, Section 4.3).Check ntCS detects the ntCS C1 having nodes (0, 1, 2) and adds C1 to ntCSs, and F ind ntCS ends as no more unvisited outgoing edges are available.
No ntCS was detected (the final path contains only cycles with back edges).After backtracking, the path is (1, 2) and the unvisited outgoing edges 2 → 3 and 3 → 4 are followed resulting in the final path (1,2,3,4).Because edge 4 → 1 was already visited, the algorithm will not follow it and stops because there are no unvisited outgoing edges.Again, no ntCS was found during path construction.Overall, the algorithm could not construct a ntCS without back edges in this case and the wCC was not classified as ntCS even though, a subgraph containing a ntCS without back edges can be constructed.To avoid this situation, back edges are not followed immediately by the algorithm.Instead, they are stored (lines 10-13) and all stored back edges are followed (lines 20-30), if there are no more unvisited incoming edges (line 20) and no other outgoing edges of the last node of the path (handled before, lines 8-19).Thus, after following edge 1 → 2, the implemented algorithm will always follow edge 2 → 3 and always store edge 2 → 1 when starting at node 1, regardless, which edge is handled first in the for loop.Only after all incoming edges of this node are marked, the stored back edges are followed.Instead of checking all incoming edges for being marked, a counter of incoming edges is used for efficiency reasons (lines 1, 20).All incoming edges being marked is equivalent to the counter of incoming edges being larger than or equal to the number of incoming edges as each incoming edge is exactly used once (all edges are visited by the algorithm).
The back edges need to be followed to find all ntCSs as the next example shows.Considering the same wCC as before, let the algorithm start at node 2 (Figure 4(d)).Further, let it follow the edges 2 → 1 and 1 → 4 and storing the edges 4 → 1 and 1 → 2 as back edges (both nodes 1 and 4 have unvisited incoming edges).After backtracking to node 2, it follows edges 2 → 3 and 3 → 4. As there are no more unvisited outgoing edges and no more unvisited incoming edges of node 4, it retrieves and follows the stored back edge 4 → 1 at node 4. The same situation occurs at node 1, and back edge 1 → 2 is retrieved and followed at node 1 yielding the path (2, 3, 4, 1, 2).ntCS C1 is detected as node 2 was visited before by the current path.
All other possible cases for this wCC are similar to those explained above.Therefore, the wCC will always be classified as ntCS.

Checking a Path for being a (Partial) ntCS
If F ind ntCS finds a node that was already marked, it calls Check ntCS.Check ntCS (Algorithm 4) examines if a sequence of nodes in this path can form (a part of) a ntCS.First, some variables are initialized: the size of the path (line 1), the last node of the path (line 2), and the last and the second to last position of the last node in the path (lines 3-4).Second, it is checked if the last node and the second to last node belong to the same ntCS (lines 5-9).If so, no new ntCS has been found and the algorithms terminates returning "no ntCS found".
To identify the sequence of nodes potentially forming a new ntCS, the algorithm starts searching over all nodes in the path starting from the last node (the already traversed node) in reverse order and stopping when it finds the same node again (lines 10-15).Starting at the end and in reverse order is necessary, because due to the construction of the path, the last node could be multiple times in the path.This is a consequence of the handling of back edges and the potential existence of trivial cycles in the path.Now, four cases might occur: (1) a trivial cycle was found (lines 16-18), (2) a ntCS was found (lines 19-27), (3) a partial ntCS was found (lines 28-29), or (4) no ntCS was found (line 31).A trivial cycle occurs when an edge is directly followed by its back edge, e.g., if a node is connected to the current node only by these two edges (Case 1).This case is handled by lines 16-18 of the algorithm and the algorithm terminates with "no ntCS found".
Next, it is checked if the last node occurs a second time in the path (line 19, Case 2).If yes, then the algorithm invokes ComputeReducedP ath (Algorithm 5) to exclude double edges that are only parts of trivial cycles (line 20).If the reduced path is not empty (line 21), the algorithm constructs a new ntCS based on the nodes in the reduced path (lines 22-23, Section 4.3.1).If the ntCS found is not a part of a previously found ntCS, it is added to the list of all ntCSs (line 24, SubCycle [1]).Finally, all ntCSs found until now are combined, if they have shared nodes or edges (line 25, M ergeCycles [1]) and the algorithm returns "ntCS found".Two examples illustrating this part of the algorithm will be given below (Section 4.3.2).
If the last node in the path occurs only once in the path, it is checked whether the last node already belongs to a ntCS (line 28, Case 3).If it does, the algorithm checks if the sequence of nodes in the path is part of a larger ntCS that can be constructed reusing the nodes of an existing ntCS (line 29, P artialCycle [1]).Two examples illustrating this situation are given below (Section 4.3.3).
Otherwise, no (part of a) ntCS could be found and the algorithm returns "no ntCS found" (line 31, Case 4).

Computing the Reduced Path
The algorithm ComputeReducedP ath (Algorithm 5) determines a reduced path that could be part of a ntCS.Therefore, it removes connections between subgraphs that consist of double edges only from the input path.An example is shown in Figure 5 where two ntCSs are connected by the double edge (e3, e8).First (lines 1-5), a copy of the input path is created.If the double edge is formed by the first and the last edge of the reduced path, then an empty path is returned (lines 6-7).In the case, that another part of the input path already forms a ntCS, this ntCS will be detected by the Algorithms 2-4.Otherwise, all edges of the reduced path starting from the first are used to construct test edges, which are potential back edges (lines 8-21).If a back edge is found, all nodes between these two edges are removed from the path (lines 15-17).Moreover, the second occurrence of the start node of the edge is removed from the path (lines 18-20).

Examples of Combining ntCSs
Two examples of combining ntCSs sharing one node and sharing one edge, respectively, will be presented next (Figures 6 and 7).
Shared Nodes An example for ntCSs sharing nodes is depicted in Figure 6.

Examples of Handling Partial ntCSs
This example deals with handling partial ntCSs (P articalCycle [1]).Let us assume that C1 is detected as shown in Figure 8 ).Now, node 3 belongs already to ntCS C1.Therefore, for each node in the current path-from the last to the first-it is checked, if the node belongs to C1, too.In the example, this holds for node 2. Thus, the partial ntCS C' = {2, 4, 5, 3} is created and merged into C1.
All previously shown cases are the basic ones that can occur while decomposing a weakly connected component.All other weakly connected components contain these basic cases (or reduced versions thereof).

Complexity Analysis
Let n = |V | denote the number of nodes, e = |E| the number of edges, and c the number of ntCSs of a directed graph G. Tables 1-4 show the complexity of the ntCS detection algorithms providing additional information compared to [1].
The overall time and space complexity of ntCS detection is O(c 3 •n 2 •(n+e)).They are dominated by calling F ind ntCS (Algorithm 2, line 6) for each not visited node, whose time and space complexity equals O(c 3 •n•(n+e)) (Table 1).
The time and space complexity of F ind ntCS are dominated by the time and space complexity of Check ntCS (Algorithm 4, line 3).
Performing constant operations, F ind ntCS Rec (Algorithm 3) has time and space complexity equal O(1) (Table 2).Please note, that the time and space complexity of calling F ind ntCS Rec from F ind ntCS (Algorithm 1) in line 16 and line 26 are constant because F ind ntCS Rec can be considered being an inline block or part of F ind ntCS which is introduced to avoid duplicated code.
Check ntCS (Algorithm 4) has time and space complexity being equal to O(c 3 •n•(n+e)) (Table 3).They are dominated by the time and space complexity of P artialCycle (line 29, [1]).
ComputeReducedP ath has time and space complexity equal to O(n) (Table 4).Both are dominated by list iteration at lines 3-5 and lines 11-21.The resulting isolated nodes forming one wCC each are ignored, as they belong to a single ntCS, only.The remaining two wCCs, however, contain edges and require further analysis before the categorization step (Section 6).A closer analysis of the different configurations that might occur shows that these wCCs could be further decomposed by splitting them at nodes of the ntCSs found (Figure 10(c)): • The green, the orange, and the red wCCs are only attached to C1 at nodes 1, 3, and 1, respectively.
Thus, we can distinguish between those parts of the wCC that are only connected to one ntCS and those that connect two or more ntCSs.This is an important fact that can later be used for an improved layout of the graph [1,2].

Algorithms
After removing the edges of the ntCSs, each node of each ntCS is taken as starting point of the split algorithm if it still has incoming or outgoing edges.These nodes are the potential split points examined by the algorithm; isolated    nodes are ignored.All edges of the wCC are treated as being undirected.For each node, all unvisited edges are followed.From the end node of each of the edges, a depth first search is started.A traversed edge will not be considered again.The depth first search backtracks, if the end node of an edge has no unchecked edges or if it belongs to a ntCS.Finally, each wCC found is added to the list of all wCCs.
The split is mainly performed by two functions: Split wCC at N ode (Algorithm 6) and Split wCC (Algorithm 7).For each ntCS node, Split wCC at N ode follows all unvisited edges of the node (lines 5-6), creating a set to add all nodes in the sub-wCC (line 7), and adding the ntCS node to this set (line 8).Then, Split wCC at N ode calls Split wCC to start the depth first search from the end node of the current edge considering the edges as being undirected (line 9).Finally, the wCC is formed from the set of nodes (line 10) and is added to the list of all wCCs (line 12), if it is not empty.
The Split wCC algorithm (Algorithm 7) performs a depth first search.First, the current edge is marked as visited (line 1) as well as its reverse edge if it exists (lines 2-5) as edges are treated ignoring their direction and therefore edge and reverse edge are considered being the same.Then, the next node in the depth first search is determined (lines 6-10).If this node is a ntCS node of the initial wCC (line 11), no further edges are followed, and the node is added to the set of all ntCS nodes of this wCC (line 12) and to the set of all nodes (line 13).It might have been visited before as it is a split point being shared by more than one sub-component.Therefore, it is added to each of the sub-components.Moreover, the node might have unvisited edges that will be handled later by the split algorithm.Otherwise (lines 14-22), the node is not a ntCS node.If it was not visited before (line 14), it is marked as visited (line 15) and added to the set of all nodes (line 16).All unvisited edges of the node are then followed calling Split wCC recursively (lines 17-22).If the node is marked and not a ntCS node, then either all edges were already followed or will be followed.Thus, this case is already handled implicitly.
Considering the example in Figure 10(c), Split wCC at N ode is called for the ntCS nodes 1 and 3. Starting at node 1, it will traverse the edges 1 → 5 (red), 1 ↔ 9 (green), and 13 → 1 (brown), one after the other.Thereby, the order is not important.Starting with edge 1 → 5, the edge is marked as visited, an empty set is created, node 1 is added to the set, and Split wCC is called to start the depth first search at node 5.After completing the search, the set of nodes contains the nodes {1, 5, 6, 7, 8} forming a new wCC (red) which will be added to the list of all wCCs.The same holds for edges 1 ↔ 9 and 13 → 1 resulting in the sets of nodes {1, 9, 10, 11, 12} (green) and {1, 13, 14, 17} (brown) forming two additional new wCCs.Handling edges 3 → 24 and 3 ↔ 18 of node 3 will produce the sets {3, 24, 25, 26, 27, 28} (orange) and {3, 18, 19, 20, 21} (blue) forming two new ntCSs, respectively.
In the cases 1 (red), 2 (green), and 4 (orange), only the else statement (lines 14-22) is executed.In the cases 3 (brown) and 5 (blue), however, the code in lines 11-13 is executed.For the last case (number 5, blue), this means that reaching node 21 for the first time, no other incoming edge is followed.The node is added to both sets and backtracking is performed.The same holds the second time, node 21 is reached.As node 21 is already contained in both sets, it is not added.The same holds the third and last time node 21 is reached.

Complexity Analysis
Let S = {wCC i } the set of all wCCs remaining after the ntCS edges were removed from the wCC being the input graph.Let wCC i = (N i , E i ) be a weakly connected component with N i being the set of nodes and E i being the set of edges.Let n i = |N i | be the number of nodes and e i = |E i | be the number of edges of wCC i .Then, the total time and space complexity of the split algorithm is O(e i ) for wCC i .This can be seen as follows.All HashSet operations have amortized time and space complexity O(1) (Tables 5 and 6).The call to algorithm Split wCC is only performed for each edge at most once (Algorithm 6, line 9 and Algorithm 7, line 20), as afterwards the edge is marked as visited (Algorithm 7, line 1).ntCS nodes might be visited several times, but their edges are only followed once when calling Algorithm 6.Thus, all ntCS nodes belonging to wCC i are reached by at most e i edges.All non-ntCS nodes are handled only once and are then marked (Algorithm 7, lines 14 and 15).Therefore, also their edges are handled only once, i.e., at most e i edges are followed (Algorithm 6, lines 4-5 and Algorithm 7, lines 17-18).Finally, the algorithm create Graph [1] is called with e i edges in sum over all split parts of wCC i .
6 Detecting Trees and DAGs

Motivation
The wCCs that result from the previous splitting step will finally be classified as down-trees, up-trees, and DAGs.Distinguishing between trees and DAGs is important, as for trees optimal drawing algorithms exist [6,9] while all algorithms for DAGs are based on heuristics [8].The distinction between down-and up-trees is made for choosing the adapted drawing algorithms, as in the first case outgoing edges will be handled while in the second case incoming edges will be handled.
The wCC of G1 shown in Figure 1(a) (Section 2) can only be classified as down-tree or up-tree (Figure 1(b), Section 2).However, the larger wCC shown in Figure 11(a) is a minimal example of a wCC that could be classified as downtree (Figure 11 Our algorithm was designed such that a wCC is classified as down-tree, if possible, as up-tree, if it can be classified as up-tree but not as down-tree, and as DAG, if no other classification is possible.The reason for preferring trees over DAGs was explained before: trees allow for improved algorithms.The choice of preferring down-trees over up-trees is arbitrary.

Detecting Trees and DAGs
To classify the wCCs, the four cases listed in Table 7 are distinguished.They take the number of source nodes n i (in-degree zero) and sink nodes n o (outdegree zero) of the respective wCC into account.In case I, n i ≥ 2 and n o ≥ 2.    Figure 11: A "star" wCC with five nodes is the minimal example of a wCC that can be transformed into a down-tree, an up-tree, and a DAG by removing the respective back-edges.
Thus, the wCC has to be a DAG and is classified as one.The other cases allow for tree or DAG classification.Cases II and III restrict the possible tree classification, while in the last case both tree classifications are possible.The cases II and III are handled using depth first search.
Then, the two counts are used for implementing the decision table presented before.In case I, the classification is DAG (lines 16-17) and a DAG is created (lines 25-27).The graph in Figure 12(a) shows an example of this case.The graph has two nodes with in-degree zero {1, 2} and three nodes with out-degree zero {5, 6, 7}.
In case II (III), the results can be either a down-tree (an up-tree) or a DAG (lines 18-19, respectively 20-21, Section 6.2.2).If it is a tree, the tree is created during the decision process by checkF orDownT ree, Algorithm 9 (checkF orU pT ree, Algorithm 11).If the construction of the down-tree (uptree) fails, the wCC is a DAG and a DAG is created.The graphs shown in Figures 12(c) and 12(d) are examples of case II.The graph in Figure 12(c) has one node with in-degree zero {1}, three nodes with out-degree zero {4, 5, 6}, and no double edges.Thus, it is a trivial down-tree.The wCC in Figure 12(d) has no nodes with in-degree zero and five nodes with out-degree zero {4, 5, 7, 8, 9}.In this case, a non-trivial down-tree can be constructed (see also Section 6.2.2).The graphs shown in Figures 12(e) and 12(f) are examples of case III.The wCC in Figure 12(e) has three nodes with in-degree zero {4, 5, 6} one node with outdegree zero {1}, and no double edges.Thus, it is a trivial up-tree.The wCC in Figure 12(f) has three nodes with in-degree zero {4, 5, 8} and no nodes with out-degree zero.In this case, a non-trivial up-tree can be constructed (see also Section 6.2.2).
In case IV, the classification is performed by calling classif y wCC (lines 22-23, Algorithm 13).As before, if the wCC is classified as a down-tree or an uptree, it is created during the classification process.Otherwise, a DAG is detected and will be created at the end (Algorithm 8, lines 25-27).In fact, this algorithm tries first to construct a down-tree (line 1).If this fails, it tries to construct an up-tree (lines 2-4).Finally, the result is returned (line 5).The wCC shown in Figure 12(b) is an example of case IV where the wCC has no nodes with indegree zero, one node with out-degree zero {4}, and one node having only double edges {1}.Starting at node 4, the construction of an up-tree fails as node 2 has three outgoing edges.Starting at node 1, the construction of a down-tree fails as node 4 has three incoming edges.Thus, the final classification is DAG.

Down-Trees and Up-Trees
The algorithm checkF orDownT ree (Algorithm 9) tries to construct a down-tree using the edges of the wCC.If the wCC does not contain double edges, then the unique trivial down-tree will be constructed.If the wCC contains double edges, it might be possible to construct one down-tree or several different down-trees.In the first case, the unique down-tree will be constructed.In the second case, one of the down-trees will be constructed.In all these cases, the wCC will be classified as down-tree.Otherwise, no down-tree can be constructed and the wCC will be classified as DAG.tree construction (Algorithms 11 and 12).Instead of outgoing edges, incoming edges are followed.The wCC shown in Figure 12(e) is a trivial up-tree with root node 1.The wCC shown in Figure 12(f) has the potential root nodes 1, 2, and 6.Nodes 1 and 6 have one double edge and node 2 has three double edges and one incoming edge.In all cases, a non-trivial up-tree can be constructed.The first non-trivial up-tree found is created as the result.

Complexity Analysis
Let n be the number of nodes, e be the number of edges, and md be the maximal degree of a node of the wCC to be classified.Then, the total time and space complexity of detecting trees and DAGs is O(n 2 •md+e) (Table 8).It is dominated by the tree detection algorithms checkF orDownT ree and checkF orU pT ree (Table 9).Both have time and space complexity O(n 2 • md + e).Therefore, also algorithm classif y wCC has the same time and space complexity (Table 11).Creating the lists of potential root nodes and computing the two counters can be done in O(n + e) as each edge is checked at most twice: once for the source and once for the target node.Creating the DAG can also be done in O(n + e) time and space.
Algorithm checkF orDownT ree (checkF orU pT ree) has time and space complexity O(n 2 • md + e).The e comes from the down-tree (up-tree) construction (lines 12 and 30); at most one down-tree (up-tree) is constructed.The factor n • md of the first summand comes from the recursive construction of the downtree using checkF orDownT reeDF S (up-tree, checkF orU pT reeDF S).The factor n of the first summand comes from the worst case example.The time and space complexity of the down-tree (up-tree) construction checkF orDownT reeDF S (checkF orU pT reeDF S) is O(n • md).For each outgoing edge of a node (limited by the maximal node degree md) two indices are computed and a recursive call is performed.The recursive call is limited by the number of nodes n, as at most one node is visited twice before the final classification.
Finally, algorithm classif y wCC has time and space complexity O(n•md+e) as it essentially calls the algorithms checkF orDownT ree and checkF orU pT ree (Algorithms 9 and 11) whose time and space complexity are O(n • md + e).

Conclusion
To create a topological visualization of directed graphs, a new methodology was previously introduced [1,2].Here, an intermediate level description of the decomposition process introduced there is provided as complementary description to the previous high [2] and low [1] level descriptions.The focus in this paper is on the motivation of the process and of each of the steps as well as on illustrative examples of all cases that need to be considered by the algorithm, standard as well as more complex ones.All other situations include those described here.
All algorithms are complemented by their complexity analysis.It shows, that the detection of non-trivial cyclic subgraphs has O(c 3 •n 2 •(n+e)) as overall time and space complexity, where n designates the number of nodes, e the number of edges, and c the number of cycles found; splitting weakly connected components resulting from removing the edges of the non-trivial cyclic subgraphs can be performed in O(e i ) as total time and space complexity where e i is the number of edges of each of the weakly connected components, respectively; and classifying the resulting weakly connected components as trees and DAGs can be performed in O(n 2 •md+e) total time and space complexity, where n designates the number of nodes, e the number of edges, and md is the maximum degree of a node of the weakly connected component.

A Algorithms for Detecting Non-Trivial Cyclic Subgraphs
Algorithm  if node has in-degree 0 then else if node has out-degree 0 then else if node has only double edges then  else if node has only double and incoming edges then

Definition 2 . 1 (Corollary 2 . 4
Trivial Cycle) A trivial cycle is a set of edges {(a, b), (b, a)}, a, b ∈ V and (a, b), (b, a) ∈ E that form a cycle of two nodes.We say, the trivial cycle contains the nodes a, b.Definition 2.2 (Back Edge) Let {(a, b), (b, a)} be a trivial cycle.Then, (b, a) is the back edge of (a, b) and vice versa.Definition 2.3 (Double Edge) The set of edges {(a, b), (b, a)}, a, b ∈ V and (a, b), (b, a) ∈ E is called double edge.Each double edge gives rise to a trivial cycle.Definition 2.5 (Non-Trivial Cycle) A non-trivial cycle is a cycle that is not trivial.Corollary 2.6 A non-trivial cycle consists of at least three edges and contains at least three nodes.

Figure 1 :
Figure 1: Two strongly connected components G1 and G2 and the resulting graphs when removing back edges from them.

Figure 4 :
Figure 4: ntCSs that are only reliably detected by handling back edges separately

Figure 5 :
Figure 5: Two ntCSs that are connected by one double edge (trivial cycle) are considered to be two separated ntCSs.

Figure 7 :
Figure 7: Two combined ntCSs sharing one edge

Figure 10 (
Figure10(a) shows the situation of a wCC after detecting ntCSs.In this case, the ntCSs C1, C2, and C3 were detected.If all edges of these ntCSs are temporarily removed from this wCC, two types of wCCs remain (Figure10(b)).The resulting isolated nodes forming one wCC each are ignored, as they belong to a single ntCS, only.The remaining two wCCs, however, contain edges and require further analysis before the categorization step (Section 6).A closer analysis of the different configurations that might occur shows that these wCCs could be further decomposed by splitting them at nodes of the ntCSs found (Figure10(c)): One wCC after detecting ntCSs (marked using blue circles).
The graph obtained after deleting the edges of the ntCSs found.
Splitting the two wCCs with edges at the ntCSs nodes results in five wCCs in the final decomposition.

Figure 10 :
Figure 10: Removing the edges of the ntCSs detected and splitting the remaining wCCs with edges at the ntCSs nodes.
The original wCC, a star with 5 nodes and 4 double edges.
Removing back-edges to obtain a down-tree.
Removing back-edges to obtain an up-tree.
Removing back-edges to obtain a DAG.
Non-trivial up-tree

Figure 12 :
Figure 12: Examples of trees and DAGs.

9 :
Add node to potentialDoubleRoots ArrayList 10:else if node has only double and outgoing edges then

Table 5 :
Complexity analysis of Split wCC at N ode (Algorithm 6)