You can also use bidirectional dfs to calculate the strongly connected component. The Tarjan algorithm template is provided here, which is more suitable for deformation.
 
Also paste the two-way dfs code.
 
 
 
Code Tarjan (this is a code with comments on the Internet, which is very detailed ):
 
[Cpp]
# Include <iostream>
# Include <cstring>
# Include <cstdio>
# Include <cstdlib>
Using namespace std;
 
# Define maxn10010
# Define MAXM 100010
 
Struct Edge
{
Int v, next;
} Edge [MAXM]; // edge node Array
 
Int first [MAXN], stack [MAXN], DFN [MAXN], Low [MAXN], Belong [MAXM];
// First [] header node array, stack [] is the stack, DFN [] is the deep search order array, and Belong [] is the strongly connected component number array corresponding to each node
// Low [u] is the number of the first node in the stack that can be traced back to the u node or the u node.
Int instack [10010]; // instack [] indicates whether to mark the array in the stack.
Int n, m, cnt, scnt, top, tot;
 
Void init ()
{
Cnt = 0;
Scnt = top = tot = 0; // initialize the connectivity component number, order counter, and stack top pointer to 0
Memset (first,-1, sizeof (first ));
Memset (DFN, 0, sizeof (DFN); // The Node search order number array is 0, and can be used when the accessed array is used
}
 
Void read_graph (int u, int v) // construct an adjacent table
{
Edge [tot]. v = v;
Edge [tot]. next = first [u];
First [u] = tot ++;
}
 
Void Tarjan (int v) // use the Tarjan algorithm to calculate the strongly connected component of a directed graph.
{
Int min, t;
DFN [v] = Low [v] = ++ tot; // cnt is the timestamp.
Instack [v] = 1; // tag in stack
Stack [top ++] = v; // inbound stack
For (int e = first [v]; e! =-1; e = edge [e]. next)
{// Enumerate each edge of v
Int j = edge [e]. v; // edge adjacent to v
If (! DFN [j])
{// Not accessed
Tarjan (j); // continue searching
If (Low [v]> Low [j]) Low [v] = Low [j]; // the minimum number of times that node v can reach
}
Else if (instack [j] & DFN [j] <Low [v])
{// If the j node is in the stack,
Low [v] = DFN [j];
}
}
If (DFN [v] = Low [v])
{// If node v is the root of the strongly connected component
Scnt ++; // join component number plus 1
Do
{
T = stack [-- top]; // return stack
Instack [t] = 0; // The tag is not in the stack.
Belong [t] = scnt; // The output stack node t is a strongly connected component of the cnt label.
} While (t! = V); // until v is exited from the stack
}
}
 
Void solve ()
{
For (int I = 1; I <= n; I ++) // enumerate each node and search for connected components
If (! DFN [I]) // not accessed
Tarjan (I); // The connected component of the I node.
}
 
Int main ()
{
While (scanf ("% d", & n, & m) & (n | m ))
{
Init ();
While (m --)
{
Int u, v;
Scanf ("% d", & u, & v );
Read_graph (u, v );
}
Solve (); // Strongly Connected Component
If (scnt = 1) printf ("Yes \ n"); // only one strongly connected component, indicating that each node in the figure is reachable
Else printf ("No \ n ");
}
Return 0;
}
 
# Include <iostream>
# Include <cstring>
# Include <cstdio>
# Include <cstdlib>
Using namespace std;
 
# Define maxn10010
# Define MAXM 100010
 
Struct Edge
{
Int v, next;
} Edge [MAXM]; // edge node Array
 
Int first [MAXN], stack [MAXN], DFN [MAXN], Low [MAXN], Belong [MAXM];
// First [] header node array, stack [] is the stack, DFN [] is the deep search order array, and Belong [] is the strongly connected component number array corresponding to each node
// Low [u] is the number of the first node in the stack that can be traced back to the u node or the u node.
Int instack [10010]; // instack [] indicates whether to mark the array in the stack.
Int n, m, cnt, scnt, top, tot;
 
Void init ()
{
Cnt = 0;
Scnt = top = tot = 0; // initialize the connectivity component number, order counter, and stack top pointer to 0
Memset (first,-1, sizeof (first ));
Memset (DFN, 0, sizeof (DFN); // The Node search order number array is 0, and can be used when the accessed array is used
}
 
Void read_graph (int u, int v) // construct an adjacent table
{
Edge [tot]. v = v;
Edge [tot]. next = first [u];
First [u] = tot ++;
}
 
Void Tarjan (int v) // use the Tarjan algorithm to calculate the strongly connected component of a directed graph.
{
Int min, t;
DFN [v] = Low [v] = ++ tot; // cnt is the timestamp.
Instack [v] = 1; // tag in stack
Stack [top ++] = v; // inbound stack
For (int e = first [v]; e! =-1; e = edge [e]. next)
{// Enumerate each edge of v
Int j = edge [e]. v; // edge adjacent to v
If (! DFN [j])
{// Not accessed
Tarjan (j); // continue searching
If (Low [v]> Low [j]) Low [v] = Low [j]; // the minimum number of times that node v can reach
}
Else if (instack [j] & DFN [j] <Low [v])
{// If the j node is in the stack,
Low [v] = DFN [j];
}
}
If (DFN [v] = Low [v])
{// If node v is the root of the strongly connected component
Scnt ++; // join component number plus 1
Do
{
T = stack [-- top]; // return stack
Instack [t] = 0; // The tag is not in the stack.
Belong [t] = scnt; // The output stack node t is a strongly connected component of the cnt label.
} While (t! = V); // until v is exited from the stack
}
}
 
Void solve ()
{
For (int I = 1; I <= n; I ++) // enumerate each node and search for connected components
If (! DFN [I]) // not accessed
Tarjan (I); // The connected component of the I node.
}
 
Int main ()
{
While (scanf ("% d", & n, & m) & (n | m ))
{
Init ();
While (m --)
{
Int u, v;
Scanf ("% d", & u, & v );
Read_graph (u, v );
}
Solve (); // Strongly Connected Component
If (scnt = 1) printf ("Yes \ n"); // only one strongly connected component, indicating that each node in the figure is reachable
Else printf ("No \ n ");
}
Return 0;
}
 
 
Bidirectional DFS:
 
[Cpp]
# Include <iostream>
# Include <cstring>
Using namespace std;
Const int n= 10010;
Const int M = 100010;
Struct Edge
{
Int v, next;
} Edge1 [M], edge2 [M];
 
Int vis1 [N], vis2 [N];
Int tot1, tot2;
Int first1 [N], first2 [N];
Int num [N];
Int cn, ans;
Int belong [N];
Int a, B, n, m, j;
Void init ()
{
Ans = 0; tot1 = tot2 = 0; cn = 0;
Memset (first1,-1, sizeof (first1 ));
Memset (first2,-1, sizeof (first2 ));
Memset (vis1, 0, sizeof (vis1 ));
Memset (vis2, 0, sizeof (vis2 ));
}
Void add_edge (int a, int B)
{
Tot1 ++;
Edge1 [tot1]. v = B;
Edge1 [tot1]. next = first1 [a];
First1 [a] = tot1;
Tot2 ++;
Edge2 [tot2]. v =;
Edge2 [tot2]. next = first2 [B];
First2 [B] = tot2;
}
Void DFS_1 (int v)
{
Vis1 [v] = 1;
For (int I = first1 [v]; I! =-1; I = edge1 [I]. next)
{
If (! Vis1 [edge1 [I]. v])
DFS_1 (edge1 [I]. v );
}
Num [cn ++] = v;
}
Void DFS_2 (int v)
{
Vis2 [v] = 1;
For (int I = first2 [v]; I! =-1; I = edge2 [I]. next)
{
If (! Vis2 [edge2 [I]. v])
DFS_2 (edge2 [I]. v );
}
}
Int main ()
{
While (cin> n> m, n | m)
{
Init ();
For (int I = 0; I <m; I ++)
{
Cin> a> B;
Add_edge (a, B );
}
For (int I = 1; I <= n; I ++)
{
If (! Vis1 [I])
{
DFS_1 (I );
}
}
For (int I = cn-1; I> = 0; I --)
{
If (! Vis2 [num [I])
{
DFS_2 (num [I]);
Ans ++;
}
}
If (ans = 1)
Cout <"Yes" <endl;
Else
Cout <"No" <endl;
 
}
Return 0;
}
 
# Include <iostream>
# Include <cstring>
Using namespace std;
Const int n= 10010;
Const int M = 100010;
Struct Edge
{
Int v, next;
} Edge1 [M], edge2 [M];
 
Int vis1 [N], vis2 [N];
Int tot1, tot2;
Int first1 [N], first2 [N];
Int num [N];
Int cn, ans;
Int belong [N];
Int a, B, n, m, j;
Void init ()
{
Ans = 0; tot1 = tot2 = 0; cn = 0;
Memset (first1,-1, sizeof (first1 ));
Memset (first2,-1, sizeof (first2 ));
Memset (vis1, 0, sizeof (vis1 ));
Memset (vis2, 0, sizeof (vis2 ));
}
Void add_edge (int a, int B)
{
Tot1 ++;
Edge1 [tot1]. v = B;
Edge1 [tot1]. next = first1 [a];
First1 [a] = tot1;
Tot2 ++;
Edge2 [tot2]. v =;
Edge2 [tot2]. next = first2 [B];
First2 [B] = tot2;
}
Void DFS_1 (int v)
{
Vis1 [v] = 1;
For (int I = first1 [v]; I! =-1; I = edge1 [I]. next)
{
If (! Vis1 [edge1 [I]. v])
DFS_1 (edge1 [I]. v );
}
Num [cn ++] = v;
}
Void DFS_2 (int v)
{
Vis2 [v] = 1;
For (int I = first2 [v]; I! =-1; I = edge2 [I]. next)
{
If (! Vis2 [edge2 [I]. v])
DFS_2 (edge2 [I]. v );
}
}
Int main ()
{
While (cin> n> m, n | m)
{
Init ();
For (int I = 0; I <m; I ++)
{
Cin> a> B;
Add_edge (a, B );
}
For (int I = 1; I <= n; I ++)
{
If (! Vis1 [I])
{
DFS_1 (I );
}
}
For (int I = cn-1; I> = 0; I --)
{
If (! Vis2 [num [I])
{
DFS_2 (num [I]);
Ans ++;
}
}
If (ans = 1)
Cout <"Yes" <endl;
Else
Cout <"No" <endl;
 
}
Return 0;
}