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 down, found 6 dfn[6] has value, has been visited. Whatever it is.
Continue 5 down, find 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])
OK, in this strongly connected component tree, 5 nodes are later than 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)
This time is over?!
You think you're done?
However not finished, in case you only walked once Tarjan the whole picture did not find out how to do?!
So. The Tarjan call is best solved in the loop.
Like if this point has not been visited, then start Tarjan again from this point.
Because it's so good that every point is accessed.
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]=++tot;//the initialization of the new input point. -Stack[++index]=x;//Pit Stop +visit[x]=1;//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);//go down and start recursion -Low[x]=min (LOW[X],LOW[EDGE[I].V]);//recursive, compare who's son/father, is the tree correspondence, involving strong connected sub-quantum tree the smallest root of things. - } - Else if(VISIT[EDGE[I].V]) {//if it has been accessed and is still in the stack. inLow[x]=min (LOW[X],DFN[EDGE[I].V]);//compare who is 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 of the 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); - } Wu for(intI=1; i<=n;i++) - if(! Dfn[i]) Tarjan (1);//When this point has not been visited, it begins at this point. Prevent the picture from going through About return 0; $}
COPYRIGHT©2017 the Hedgehog's glass is broken.
"Reprint" The whole network most! detailed!tarjan algorithm explained.