Tarjan algorithm "Java implementation" for strongly connected component of a forward graph

Source: Internet
Author: User


Note: The contents of this article are reproduced from http://www.cppblog.com/sosi/archive/2010/09/26/127797.html, on the one hand, there are many online Tarjan algorithm introduction, I don't think so. The simplicity of his article is straightforward or does not have a specific implementation. On the other hand, I also conveniently used Java to achieve a bit, so publish and share with you!






[Strong connected component of the graph]



In a direction diagram G, if there is at least one path between two vertices, the two vertices are strongly connected (strongly connected). If there is a strong connection to each of the two vertices of the graph G, G is a strongly connected graph. The maximal strongly connected subgraph of a undirected graph of a non strongly connected graph is called a strongly connected component (strongly connected components).



In the following figure, the child figure {1,2,3,4} is a strongly connected component because the vertex 1,2,3,4 22 is up to. {5},{6} is also two strong connected components respectively.










[Tarjan algorithm]



The Tarjan algorithm is based on the depth-first search algorithm, and each strong-connected component is a Shang tree in the search tree. When searching, the unhandled nodes in the current search tree are added to a stack, and backtracking can be used to determine whether the node in the stack is a strong connected component.






Define DFN (U) d records the time of search to the U, which is the first few search U. Low (U) is the order number of the nodes in the earliest stack that the subtree of U or u can trace back to.









algorithm pseudo code is as follows



Tarjan (U)
{



Dfn[u]=low[u]=++index//Set sequence number and low initial value for node U



Stack.push (U)//Push the node u into the Stack



For every (U, v) in E//enumerate each edge



If (V is not visted)//If node V has not been accessed



Tarjan (v)//continue looking down



Low[u] = min (Low[u], low[v])



else if (v in S)//If node V is still in the stack



Low[u] = min (Low[u], dfn[v])



if (dfn[u] = = Low[u])//IF node U is the root of a strongly connected component



Repeat



v = s.pop//V-back stack, a vertex for the strongly connected component



Print V



Until (u== v)



}









The next step is to demonstrate the algorithm flow. DFS is started from Node 1, and the nodes that are traversed are added to the stack. When the node u=6 was searched, Dfn[6]=low[6], a strong connected component was found. {6} is a strong connected component until the stack is u=v.







Return node 5, find Dfn[5]=low[5], after which {5} is a strong connected component.







Return to Node 3, continue searching to node 4, and add 4 to the stack. found that node 4 to Node 1 has a back edge, node 1 is still in the stack, so low[4]=1. Node 6 has been out of the stack, (4,6) is the cross side, returned 3, (3,4) for the edge of the tree, so low[3]=low[4]=1.







Go back to Node 1 and finally Access Node 2. Access Edge (2,4), 4 is still on the stack, so low[2]=dfn[4]=5. After returning 1, Discover Dfn[1]=low[1], take out all the nodes in the stack and form a connected component {1,3,4,2}.










At this point, the algorithm is over. Through this algorithm, we find out all three strong connected components {1,3,4,2},{5},{6} in the graph. It can be found that in the process of running the Tarjan algorithm, each vertex is accessed once, and only one stack is in and out, each edge is only accessed once, so the time complexity of the algorithm is O (n+m).



The algorithm Java implementation is as follows:



Tarjan class:




import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Stack;
public class Tarjan {
private int numOfNode;
Private list < ArrayList < integer > > graph; / / figure
Private list < ArrayList < integer > > result; / / save the most strongly connected graph
Private Boolean [] instack; / / whether the node is in the stack, because it is not convenient to find a node in the stack. This way to find fast
private Stack<Integer> stack;
private int[] dfn;
private int[] low;
private int time;//
public Tarjan(List< ArrayList<Integer> > graph,int numOfNode){
this.graph = graph;
this.numOfNode = numOfNode;
this.inStack = new boolean[numOfNode];
this.stack = new Stack<Integer>();
dfn = new int[numOfNode];
low = new int[numOfNode];
Arrays. Fill (DFN, - 1); / / set all elements of DFN to - 1, where DFN [i] = - 1 means I has not been accessed.
Arrays.fill(low, -1);
result = new ArrayList<ArrayList<Integer>>();
}
public List< ArrayList<Integer> > run(){
for(int i=0;i<numOfNode;i++){
if(dfn[i]==-1){
Tarjan (I);
}
}
return result;
}
public void tarjan(int current){
dfn[current]=low[current]=time++;
inStack[current]=true;
stack.push(current);
for(int i=0;i<graph.get(current).size();i++){
int next = graph.get(current).get(i);
If (DFN [next] = = - 1) {/ / - 1 means not accessed
tarjan(next);
low[current]=Math.min(low[current], low[next]);
}else if(inStack[next]){
low[current]=Math.min(low[current], dfn[next]);
}
}
if(low[current]==dfn[current]){
ArrayList<Integer> temp =new ArrayList<Integer>();
Int j = -1;
while(current!=j){
j = stack.pop();
inStack[j]=false;
Temp.add (J);
}
result.add(temp);
}
}
} 
Test class:








Import java.util.ArrayList;
Import java.util.List;
Import Java.util.Stack;


public class Main {public
	static void Main (string[] args) {
                //create figure
		int numofnode = 6;
		list< arraylist<integer> > Graph = new arraylist<arraylist<integer>> ();
		for (int i=0;i<numofnode;i++) {
			graph.add (new arraylist<integer> ());
		}
		Graph.get (0). Add (1);
		Graph.get (0). Add (2);
		Graph.get (1). Add (3);
		Graph.get (2). Add (3);
		Graph.get (2). Add (4);
		Graph.get (3). Add (0);
		Graph.get (3). Add (5);
		Graph.get (4). Add (5);
		Call the Tarjan algorithm to find the maximal connected subgraph
		Tarjan t = new Tarjan (graph, numofnode);
		list< arraylist<integer> > result = T.run ();
                Print result for
		(int i=0;i<result.size (), i++) {for
			(int j=0;j<result.get (i). Size (); j + +) {
				System.out.print (Result.get (i). Get (J) + "");
			}
			System.out.println ();}}






Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.