Hdu1269 strongly connected Template

Source: Internet
Author: User

 

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;
}

 
 

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.