The most detailed Tarjan algorithm explained in the whole network, I dare not say anything else. Anyway, other Tarjan algorithm explained, I looked at half a day to understand. I wrote this, read it once, found that the original Tarjan so simple!
Tarjan algorithm, a magic algorithm about the connectivity of graphs. Based on DFS (di mage) algorithm, depth first search for a map. Attention! is a graph of direction. The work of dissecting a diagram is done by means of a tree, stack, marker, and other gods (che) odd (Dan) method. And the diagram of the connectivity, that is, the two-pulse of the governor does not pass. The problem.
Before understanding the Tarjan algorithm you need to know:
Strong connectivity, strong connected graphs, strongly connected components, solution trees (solution trees are just one form.) Understand)
Do not know how to do!!!
Magic Conch ~: Disorderly pile Chatter ~!
Changliantong (strongly connected): In a graph G, set two points a B found that a road from a can go to B, from B and a way to go to a, we call these two vertices (a, B) strong connectivity.
Strong Connect graph: If in a graph G, every two points are strong connectivity, we call this graph, strong connected graph.
Strongly connected component strongly connected components): In a directed graph G, there is a sub-graph, which satisfies strong connectivity every 2 points, we call this sub-graph called the strongly connected component [component:: A vector that decomposes a vector into several directions, The vectors in those directions are called the components of the vector (the pre-decomposed vector).
To give a simple chestnut:
For example, in this diagram, point 1 and point 2 each have a path to each other, so they are strongly connected.
In this graph, the sub-graph of point 1 2 3 is the strong connected component of the whole graph.
Solution Tree: A tree that can be used to express recursive enumeration (figure), in fact, it can be said to be recursive graph. Anyway, it is a function, a show from the "Nothing to do" start to "all knot to find out" process of gradual completion. Process ”
Magic Conch End!!!
The Tarjan algorithm uses DFS because it takes each strong connected component as a subtree on the search tree. And this diagram is a complete search tree.
In order for this search tree to run smoothly when it encounters nodes with strong connected components. Each point has two parameters.
1,dfn[] as the order number (timestamp) of this point search, in simple terms is the first few to be searched. % the timestamp for each point is not the same as%.
2,low[] As each point in this tree, the root of the smallest subtree, each guaranteed to be minimal, like its Father node timestamp this feeling. If its own low[] is the smallest, then this point should be reassigned to become the root node of this strongly connected sub-quantum tree.
PS: Find a new point each time, this point low[]=dfn[].
and in order to store the entire strongly connected component, the container selected here is the stack. Each time a new node appears, the pit stop, if the point has a degree to continue to look down. Until you find the bottom, each return up to look at the sub-node and the low value of this node, who is small to take who, to ensure the smallest subtree. If dfn[]==low[] is found, the node is the root node of the strongly connected component (after all, this low[] value is the smallest of the strongly connected component. Finally, after finding the node of the strong connected component, the stack is all out of the stack after this node, and they form a completely new strong connected component.
First, a pseudo-code pressure yajing:
Tarjan (U) {
Dfn[u]=low[u]=++index//Set sequence number and low initial value for node U
Stack.push (U)//Press 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 the node U is still inside the stack
Low[u] = min (Low[u], dfn[v])
if (dfn[u] = = Low[u])//If the node U is the root of the strongly connected component
REPEATV = s.pop//V-Stack, a vertex in the strongly connected component
Print V
Until (u== v)
}
Let's start with a map. This map is everywhere on the internet. We're going to simulate the entire algorithm at 1.1 points.
From 1 into dfn[1]=low[1]= ++index----1
into the stack 1
From 1 into 2 dfn[2]=low[2]= ++index----2
into the Stack 1 2
followed by 2 into 3 dfn[3]=low[3]= ++index----3
into the Stack 1 2 3
followed by 3 into 6 Dfn[6]=low[6]=++index----4
into the Stack 1 2 3 6
And then found out, huh? 6 no out degree, then judge Dfn[6]==low[6]
Note 6 is the root node of a strongly connected component: 6 and 6 points out of the stack.
Stack: 1 2 3
Then return the node 3 low[3] = min (low[3], low[6]) low[3] or 3
Node 3 also no longer able to extend the side, Judge Dfn[3]==low[3]
Note 3 is the root node of a strongly connected component: 3 and 3 points out of the stack.
Stacks: 1 2
Then return the node 2, eh?! Down to Node 5
dfn[5]=low[5]= ++index-----5
into the Stack 1 2 5
PS: You will find that the ugly (crossed) search tree next to the graph is cut off by a red line, and that is a strong connected sub-tree. Find one at a time. Direct. A scissor down. Half a tree is gone.
Node 5 is looking down and found that nodes 6 dfn[6] have values and have been visited. Whatever it is.
Continue to 5 down to find the node 1 his father's father. DFN[1] has been visited and is still in the stack, indicating that 1 is still in this strongly connected component, it is worth discovering. Low[5] = min (low[5], dfn[1])
To determine the relationship, in this strongly connected component tree, 5 nodes are more likely to appear later than the 1 nodes. So 5 is the child node of 1. So
Low[5]= 1
From 5 continue back to 2 low[2] = min (low[2], low[5])
Low[2]=1;
From 2 continue back to 1 judge low[1] = min (low[1], low[2])
LOW[1] or 1?
1 and the other side did not pass. Discovery node 4, accessing node 4
Dfn[4]=low[4]=++index----6
into the Stack 1 2 5 4
By node 4, walk to 5, found 5 was visited, 5 is still in the stack,
Low[4] = min (low[4], dfn[5]) low[4]=5
Description 4 is a child node of 5.
From 4 back to 1.
Return to 1, judge low[1] = min (low[1], low[4])
LOW[1] is still 1.
Judging low[1] = = Dfn[1]
Eh?! Equal to the description of the strong connected component with 1 as the root node has been found.
All the points in the stack after 1 and 1 are stacked.
Stack: (No ghosts)
and exit the entire recursion, the whole picture, also by our search completed. Tarjan algorithm. That's one thing.
To a bare code.
Input:
A graph with a map.
Output:
It each strong connected component.
This picture is the one we just talked about. Same.
Input
6 8
1 3
1 2
2 4
3 4
3 5
4 6
4 1
5 6
Output
6
5
3 4 2 1
1#include <cstdio>2#include <algorithm>3#include <string.h>4 using namespacestd;5 structNode {6 intV,next;7}edge[1001];8 intdfn[1001],low[1001];9 intstack[1001],heads[1001],visit[1001],cnt,tot,index;Ten voidAddintXinty) One { Aedge[++cnt].next=Heads[x]; -EDGE[CNT].V =y; -heads[x]=CNT; the return ; - } - voidTarjan (intx)//represents the first few points in the processing. Recursion is the point. - { +dfn[x]=low[x]=++initializes the tot;//new point. -stack[++index]=x;//Pit Stop +visit[x]=1;//means in the stack A for(inti=heads[x];i!=-1; i=edge[i].next) at { - if(!DFN[EDGE[I].V]) {//If you have not visited - Tarjan (EDGE[I].V);//Extend down, start recursion -low[x]=min (low[x],low[edge[i].v]);//recursion, compare who's son/father, is the corresponding relationship of the tree, involving strong connected sub-quantum tree the smallest root of things. - } - Else if(VISIT[EDGE[I].V]) {//if accessed, and is still in the stack. inlow[x]=min (low[x],dfn[edge[i].v]);//compare Who's son/father. is the link correspondence relationship - } to } + if(low[x]==dfn[x])//Discovery is the smallest root in the entire strongly connected sub-quantum tree. - { the Do{ *printf"%d", Stack[index]); $visit[stack[index]]=0;Panax Notoginsengindex--; -} while(x!=stack[index+1]);//out stack, and output. theprintf"\ n"); + } A return ; the } + intMain () - { $memset (heads,-1,sizeof(heads)); $ intn,m; -scanf"%d%d",&n,&m); - intx, y; the for(intI=1; i<=m;i++) - {Wuyiscanf"%d%d",&x,&y); the Add (x, y); - } WuTarjan (1);//Enter the first point. - return 0; About}
The whole network most! detailed!tarjan algorithm explained.