It's relatively simple .. Set template ..
Gabow
# Include "cstdlib" # include "cctype" # include "cstring" # include "cstdio" # include "cmath" # include "algorithm" # include "vector" # include "string" # include "iostream" # include "sstream" # include "set" # include "queue" # include "stack" # include "fstream" # include "strstream" using namespace STD; # define M 20000 // The maximum number of points possible in the question int stack [m], Top = 0; // The auxiliary stack int stack2 [m] In the gabow algorithm, top2 = 0; // int dfn [m]; // deep Degree-first search access order int componetnumber = 0; // Number of strongly connected components of the directed graph int Index = 0; // index number int belong [m]; // which connected branch of a vertex belongs to vector edge [m]; // The adjacent table indicates vector component [m]; // obtain the strongly connected component result bool bcount [m] = {0}; void gabow (int I) {Int J; dfn [I] = index ++; stack [++ top] = I; stack2 [++ top2] = I; for (int e = 0; e <edge [I]. size (); e ++) {J = edge [I] [E]; If (dfn [J] =-1) gabow (j ); else if (belong [J] =-1) // maintain stack2 {While (dfn [stack2 [top2]> dfn [J]) // Delete the vertex top2 --;} if (I = stack2 [top2]) // if the top element of stack2 is equal to I, output the corresponding strongly connected component {-- top2; ++ componetnumber; do {belong [stack [Top] = componetnumber; component [componetnumber]. push_back (stack [Top]);} while (stack [top --]! = I) ;}} void solve (INT N) // Number of vertices in the graph. Note that it is 0-indexed! {Memset (stack,-1, sizeof (stack); memset (stack2,-1, sizeof (stack2); memset (belong,-1, sizeof (belong )); memset (dfn,-1, sizeof (dfn); For (INT I = 0; I <n; I ++) if (dfn [I] =-1) gabow (I);} void reshape (INT N) // click it to form a new graph. n is the number of points in the graph {// bool comdig [m] [m]; // memset (comdig, 0, sizeof (comdig); For (INT I = 0; I <n; I ++) // a vertex is I {for (Int J = 0; j <edge [I]. size (); j ++) // The other vertex is edge [I] [J] {If (belong [I]! = Belong [edge [I] [J]) bcount [belong [I] = true; // comdig [belong [I] [belong [edge [I] [J] = true ;}/ * For (INT I = 1; I <= componetnumber; I ++) {for (Int J = 1; j <= componetnumber; j ++) {If (comdig [I] [J]) cout <I <"" <j <Endl ;}}*/}/* the basis for normal operation of this algorithm is that the figure is 0-indexed. However, the component array and belong array are 1-indexed */INT main () {int n, m; // n points, M side while (scanf ("% d", & N, & M) = 2) {int A, B; int ncount [m] = {0 }; // define the degree of output of the connected component after contraction for (INT I = 0; I <m; I ++) {scanf ("% d", &, & B); A --, B --; edge [A]. push_back (B);} int n = N; solve (n); reshape (n); int time = 0, ANS = 0; For (INT I = 1; I <= componetnumber; I ++) if (! Bcount [I]) {ans = component [I]. size (); time ++;} If (time = 1) printf ("% d/N", ANS); else printf ("% d/N ", 0);} return 0 ;}
Kosaraju
# Include "cstdlib" # include "cctype" # include "cstring" # include "cstdio" # include "cmath" # include "algorithm" # include "vector" # include "string" # include "iostream" # include "sstream" # include "set" # include "queue" # include "stack" # include "fstream" # include "strstream" using namespace STD; # define M 20000 bool vis [m]; // traverses the int post [m] array; // int timestamp corresponding to the timestamp; // timestamp int componetnumber = 0; // Number of strongly connected components of a directed graph: int belong [m]; vector edge [m]; // The adjacent table indicates vector OPP [m]; // The reverse map of the source image, vector component [m]; // obtain the strongly connected component result bool bcount [m] = {0}; void DFS (int u) {// The first DFS determines the timestamp vis [u] = true; for (INT I = 0; I <edge [u]. size (); I ++) {If (vis [edge [u] [I]) continue; // cout <edge [u] [I] <Endl; DFS (edge [u] [I]);} // cout <"timestamp" <timestamp <"" <u <Endl; post [timestamp ++] = u;} void dfs2 (int u) {// The second reverse edge DFS determines the connected block vis [u] = T Rue; component [componetnumber]. push_back (U); belong [u] = componetnumber; For (INT I = 0; I <OPP [u]. size (); I ++) {int v = OPP [u] [I]; If (vis [v]) continue; dfs2 (v );}} void kosaraju (int n) {memset (belong, 0, sizeof (belong); memset (VIS, 0, sizeof (VIS); timestamp = 0; for (INT I = 0; I <n; I ++) {If (vis [I]) continue; DFS (I) ;} memset (VIS, 0, sizeof (VIS); componetnumber ++; For (INT I = n-1; I> = 0; I --) {// search for if (vis [p Ost [I]) continue; component [componetnumber]. clear (); dfs2 (post [I]); componetnumber ++;} componetnumber --; // finally, we add 1 to the block .. Therefore, we need to subtract} void reshape (int n) // to form a new graph. n is the number of points in the graph {// bool comdig [m] [m]; // memset (comdig, 0, sizeof (comdig); For (INT I = 0; I <n; I ++) // a vertex is I {for (Int J = 0; j <edge [I]. size (); j ++) // The other vertex is edge [I] [J] {If (belong [I]! = Belong [edge [I] [J]) bcount [belong [I] = true; // comdig [belong [I] [belong [edge [I] [J] = true ;}/ * For (INT I = 1; I <= componetnumber; I ++) {for (Int J = 1; j <= componetnumber; j ++) {If (comdig [I] [J]) cout <I <"" <j <Endl ;}} * // the premise for this algorithm to work is still 0-indexed int main () {int N, m; // n points, M side while (scanf ("% d", & N, & M) = 2) {int A, B; int ncount [m] = {0}; // defines the output degree of the connected component after contraction for (INT I = 0; I <m; I ++) {scanf ("% d", & A, & B);- -, B --; edge [A]. push_back (B); OPP [B]. push_back (a);} int n = N; kosaraju (n); reshape (n); int time = 0, ANS = 0; For (INT I = 1; I <= componetnumber; I ++) if (! Bcount [I]) {ans = component [I]. size (); time ++;} If (time = 1) printf ("% d/N", ANS); else printf ("% d/N ", 0);} return 0 ;}
Tarjan
# Include "cstdlib" # include "cctype" # include "cstring" # include "cstdio" # include "cmath" # include "algorithm" # include "vector" # include "string" # include "iostream" # include "sstream" # include "set" # include "queue" # include "stack" # include "fstream" # include "strstream" using namespace STD; # define M 10005 // maximum number of points in the question int stack [m], Top = 0; // stack bool instack [m] In the Tarjan algorithm; // check whether int dfn [m] is in the stack; // Deep Priority Search access order int low [m]; // The earliest order that can be traced int componetnumber = 0; // Number of strongly connected components of the directed graph int belong [m]; int Index = 0; // The Index Number Vector edge [m]; // The adjacent table indicates vector component [m]; // obtain the strongly connected component result // bool comdig [m] [m]; bool bcount [m] = {0}; void Tarjan (int I) {Int J; dfn [I] = low [I] = index ++; instack [I] = true; stack [++ top] = I; for (int e = 0; E <edge [I]. size (); e ++) {J = edge [I] [E]; If (dfn [J] =-1) {Tarjan (j ); low [I] = min (low [I], low [J]);} else If (instack [J]) low [I] = min (low [I], dfn [J]);} If (dfn [I] = low [I]) {// cout <"TT" <I <"" <low [I] <Endl; componetnumber ++; do {J = stack [top --]; instack [J] = false; component [componetnumber]. push_back (j); belong [J] = componetnumber;} while (J! = I) ;}} void solve (INT N) // Number of vertices in the graph. Note that it is 0-indexed! {Memset (stack,-1, sizeof (stack); memset (instack, 0, sizeof (instack); memset (dfn,-1, sizeof (dfn )); memset (low,-1, sizeof (low); memset (belong, 0, sizeof (belong); For (INT I = 0; I <n; I ++) if (dfn [I] =-1) Tarjan (I);} void reshape (INT N) // click it to form a new graph, N indicates the number of points in the graph {// bool comdig [m] [m]; // memset (comdig, 0, sizeof (comdig); For (INT I = 0; I <n; I ++) // a vertex is I {for (Int J = 0; j <edge [I]. size (); j ++) // The other vertex is edge [I] [J] {If (be Long [I]! = Belong [edge [I] [J]) bcount [belong [I] = true; // comdig [belong [I] [belong [edge [I] [J] = true ;}/ * For (INT I = 1; I <= componetnumber; I ++) {for (Int J = 1; j <= componetnumber; j ++) {If (comdig [I] [J]) cout <I <"" <j <Endl ;}}*/}/* the basis for normal operation of this algorithm is that the figure is 0-indexed. */INT main () {int n, m; // n points, M side while (scanf ("% d", & N, & M) = 2) {int A, B; int ncount [m] = {0}; // defines the degree of exit of the connected component after contraction for (INT I = 0; I <m; I ++) {scanf ("% d", & A, & B); A --, B --; edge [A]. push_back (B);} int n = N; solve (n); reshape (n);/* For (INT I = 1; I <= componetnumber; I ++) {for (Int J = 0; j <componetnumber; j ++) {If (comdig [I] [J]) bcount [I] ++ ;}} */INT time = 0, ANS = 0; For (INT I = 1; I <= componetnumber; I ++) if (! Bcount [I]) {ans = component [I]. size (); time ++;} If (time = 1) printf ("% d/N", ANS); else printf ("% d/N ", 0);} return 0 ;}