From: http://kinslovertec.blogbus.com/logs/44636955.html
Common (I have seen) algorithms for strongly connected components include: 1. kosaraju algorithm (dual DFS) 2. Tarjan algorithm 3. gabow
I. kosaraju Algorithm
The Core Implementation of the algorithm is to first obtain a DFS forest and obtain the topological sequence of all vertices (from high to low by end time ), then we create an undirected graph and perform the second DFS in the reverse topology order (the end time is from high to low). Then, each tree is a strongly connected component, this figure demonstrates a better understanding. It strictly proves that it is better to refer to the introduction to 340 pages of algorithms. The perceptual knowledge is that we have two strongly connected components, C1 and C2, in the reverse topological order, C1 is prior to C2. In this case, it indicates that C2 is ended before the first DFS in G, and C1 is completed. If the point in C2 is reachable from C1, that is, when the first DFS request is sent, all the timestamp ranges of the C2 point are within the C1 range, at this time, when all the sides are reversed, C1 will have no edge to reach C2 (provided that they are indeed SCC), and the first C1 will be in the order of C2 DFS, some DFS properties are used here. It is better to read the introduction to algorithms. If they were originally two trees, then the tree in front of the rice topology would not be able to side to the back. Although this algorithm is slow, it obtains the topological order of connected components, which is sometimes used.
Ii. Tarjan Algorithm
The time efficiency of the Tarjan algorithm is better than that of kosaraju. Because the algorithm only uses DFS once, the idea of implementation is, I specify three attributes for each vertex: Tim [I] and low [I] and VST [I]. The timestamp in Tim and DFS is similar, that is, only the arrival time is recorded, low indicates that the current vertex uses its own non-tree edge (rollback edge) or the non-tree edge (rollback edge) in the subtree ), the maximum number of vertices that can be connected to the nearest root node (the current vertex must be the immediate ancestor of the current vertex or the current vertex). Tim [v]
= Low [v] = ++ times. After the DFS completes the subtree of a vertex, it is found that Tim [v] is still equal to low [v, it means that this vertex and the vertex in its subtree constitute a strongly connected component. In this process, we can use a stack to assist, and press this vertex at a point in DFS, mark instack [I]
= True. In this way, we can use the stack to determine whether the accessed vertex in the V vertex is the immediate ancestor of V (the immediate ancestor can constitute the ring ). After a DFS vertex is complete, determine whether Tim [v] is equal to low [v]. If they are equal, This vertex constitutes a strongly connected component with its subtree. Pop up the vertices in the stack until the current vertex, assign them the same strongly connected component label, and set instack [v]
= False;
I used the query set to implement the Tarjan algorithm. The process is similar to using the query set to implement dual-connected components. However, because it is an undirected graph, the current branch may still point to the sbling branch that has already been DFS. In this case, our solution is to use the dual-Time Label of DFS to mark the start and end times, based on the interval nature of the DFS label, you can determine whether an accessed vertex of V is an immediate ancestor. The implementation process of the query set is that once son is not accessed and low [son]
> = Tim [Father] and merge.
Iii. gabow
In fact, if gabow can also be listed as an algorithm, I can calculate it. The difference is that my version is slower than the original version of Tarjan, while gabow seems to be faster, the gabow algorithm uses two stacks for maintenance. stk1 is the same as the original one. stk2 is used to construct the root node of the sub-tree by means of strongly connected components. stk1, stk2, and Tarjan are the same during the insertion process, insert a vertex, and when the adjacent vertex of a vertex is his ancestor in the stack, We will pop up the vertex in stk2 until stk2 [Top]
= This adjacent vertex. The remaining vertex is probably a root node with a strongly connected component. After the DFS completes a vertex, check whether stk2 [Top] is equal to the current node, if the value is equal to the same value, it indicates that all the Subtrees of the current vertex can be rolled back to the current vertex at most, which constitutes a strongly connected component. This vertex is displayed in stk2. The stk1 operation is the same as that in Tarjan, each labeled strongly connected component number can be used. The advantage is that you do not need to modify the low value frequently. It seems that the implementation is faster and less complex than that of Tarjan, basically the same.
Hoj 2741 test results
1. gabow: 0.19 s
2. Tarjan: 0.20 s
3. Tarjan + Union-find set: 0.71 s
From: http://hi.baidu.com/365745675/blog/item/fad33d41e6ec5c1e73f05d99.html