Question :~~~~~;
Idea: Determine whether a graph is strongly connected;
The Tarjan Algorithm for Directed Graph strongly connected components:
[Digraph strongly connected component]
In directed graph G, if at least one path exists between two vertices, the two vertices are strongly connected ). If each vertex of directed graph G is strongly connected, G is a strongly connected graph. A very large strongly connected subgraph of A digraph of a non-strongly connected graph, known as strongrong connected components ).
In, the subgraph {1, 2, 3, 4} is a strongly connected component, because the vertex is reachable between 2, 2, 3, and 4. {5} and {6} are also two strongly connected components.
In general, there are three algorithms: Kosaraju, Trajan, and Gabow! We will introduce the Tarjan Algorithm in subsequent articles.
[Tarjan algorithm]
The Tarjan algorithm is based on the image depth-first search algorithm. Each strongly connected component is a subtree in the search tree. When searching, add unprocessed nodes in the current search tree to a stack. When backtracking, you can determine whether the nodes on the stack are a strongly connected component.
Define DFN (u) as the node u search order number (timestamp), Low (u) the sequence number of the earliest node in the stack that can be traced back to the u or u subtree.
The pseudo-code of the algorithm is as follows:
Tarjan (u)
{
DFN [u] = Low [u] = ++ Index // set the sequence number and Low initial value for node u
Stack. push (u) // press node u into the Stack
For each (u, v) in E // enumerate each edge
If (v is not visted) // if node v has not been accessed
Tarjan (v) // continue searching
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 the node u is the root of the strongly connected component
Repeat
V = S. pop // stack v to a vertex in the strongly connected component.
Print v
Until (u = v)
}
Next, we will demonstrate the algorithm flow.
From Node 1 to DFS, add the traversal nodes to the stack. When node u = 6 is found, DFN [6] = LOW [6] finds a strongly connected component. Stack back to u = v, {6} is a strongly connected component.
Return to node 5. DFN [5] = LOW [5] is found. After stack rollback, {5} is a strongly connected component.
Return to node 3, search for node 4, and add node 4 to the stack. It is found that node 4 has a backward edge to node 1, and node 1 is still in the stack, so LOW [4] = 1. Node 6 is out of the stack, () is the cross edge, 3 is returned, () is the branch edge, so LOW [3] = LOW [4] = 1.
Go back to node 1 and Access Node 2. The access edges (2, 4) and 4 are still in the stack, so LOW [2] = DFN [4] = 5. After 1 is returned, DFN [1] = LOW [1] is found, and all nodes in the stack are taken out to form a connected component {1, 3, 4, 2 }.
So far, the algorithm has ended. After this algorithm, all three strongly connected components {1, 3, 4, 2}, {5}, {6} in the graph are obtained }.
It can be found that each vertex is accessed once during the running of the Tarjan algorithm, and only once in and out of the stack, each side is accessed only once, therefore, the time complexity of this algorithm is O (N + M ).
AC code:
[Cpp]
# Include <stdio. h>
# Include <string. h>
# Include <vector>
Using namespace std;
Const int Max = 11000;
# Define min (a, B) a> B? B:
Int n, m, top, index;
Int instack [Max], stack [Max], loop [Max];
Int DFN [Max], LOW [Max], ans;
Vector <int> V [Max];
Void init ()
{
Top = ans = 0;
Index = 1;
Int I;
For (I = 0; I <Max; I ++)
{
V [I]. clear ();
Loop [I] = 0;
Instack [I] = 0;
}
}
Void tarjan (int u)
{
Int I, j, v;
LOW [u] = DFN [u] = index ++;
Stack [top ++] = u;
Loop [u] = 1;
Instack [u] = 1;
For (I = 0; I <V [u]. size (); I ++)
{
V = V [u] [I];
If (loop [v] = 0)
{
Tarjan (v );
LOW [u] = min (LOW [u], LOW [v]);
}
Else if (instack [v])
LOW [u] = min (LOW [u], DFN [v]);
}
If (DFN [u] = LOW [u])
{
Do {
J = stack [top-1];
Instack [I] = 0;
Top --;
} While (j! = U );
Ans ++;
}
}
Int main ()
{
Int I, j, x, y;
While (~ Scanf ("% d", & n, & m) & n + m)
{
Init ();
For (I = 1; I <= m; I ++)
{
Scanf ("% d", & x, & y );
V [x]. push_back (y );
}
For (I = 1; I <= n; I ++)
If (loop [I] = 0)
Tarjan (I );
If (ans = 1 | n = 1)
Printf ("Yes \ n ");
Else
Printf ("No \ n ");
}
}