首页 > 代码库 > 求强连通分量

求强连通分量

还是贴一份tarjan的代码吧 ,QwQ

  1 #include <algorithm>  2 #include <iostream>  3 #include <cstdlib>  4 #include <cstring>  6 #include <cstdio>  7 #include <vector>  8 #include <queue>  9 using namespace std ; 10 const int inf = 1 << 30 , maxn = 10000 + 100 , maxe = 500000 + 100 ; 11 int  n , m , cnt ,head[maxn] , tot  , top , sta[maxn], dfn[maxn] , low[maxn] , sum[maxn]; 12 struct id { 13     int to , nxt ; 14 }  edge[maxe] ; 15 bool lie[maxe] ; 16 vector< vector<int> > node( maxn ) ;  17  18  19 inline void Init(  ) { 20     freopen( "10717.in" , "r" , stdin ) ; 21     freopen( "10717.out" , "w" , stdout ) ; 22 } 23  24 int read(  ) { 25     char ch = getchar(  ) ; int ret = 0 , k = 1 ; 26     while( ch < 0 || ch > 9 ) { if( ch == - ) k = -1 ; ch = getchar(  ) ; } 27     while( ch >= 0 && ch <= 9 ) ret = ret * 10 + ch - 0 , ch = getchar(  ) ; 28     return ret * k ; 29 } 30  31  32 void add( int u , int v ) { 33     edge[++cnt].to = v ; 34     edge[cnt].nxt = head[u] ; 35     head[u] = cnt ; 36 } 37  38  39 void input(  ) { 40     n = read(  ) , m = read(  ) ; 41     int  u , v ; 42     memset( head , -1 , sizeof( head ) ) ; 43     for( int x = 1 ;  x <= m ; ++x ) { 44         u = read( ) , v = read(  ) ; 45         add( u , v ) ; 46     } 47     cnt = 0 ; 48 } 49  50  51 void scc( int u ) { 52     dfn[u] = ++tot ; low[u] = tot ; 53     sta[++top] = u ; lie[u] = true ; 54     for( int i = head[u] ; ~i ; i = edge[i].nxt ) { 55         int v = edge[i].to ; 56         if( dfn[v] == 0 )  57         { 58             scc( v ) ; 59             low[u] = min( low[u] , low[v] ) ; 60         } 61         else if( lie[v] ) { 62             low[u] = min( low[u] , dfn[v] ) ; 63         }     64     } 65     if( low[u] == dfn[u] ) { 66         cnt ++ ; 67         int front = 0 ; 68         do { 69             front = sta[top--] ; 70             sum[cnt] ++ ; 71             node[cnt].push_back( front ) ; 72             lie[front] = false ; 73              74         } while( front != u ) ; 75     } 76 } 77  78  79  80 void sov(  ) { 81     for( int x = 1 ; x <= n ; ++x ) { 82         if( dfn[x] == 0 ) scc( x ) ; 83     } 84 } 85  86  87  88 void output(  ) { 89     printf( "%d\n" , cnt ) ;     90     for( int x = 1 ; x <= cnt ; ++x ) { 91         printf( "%d " , sum[x] ) ; 92         for( int y = 0 ; y < sum[x] ; y++ )  93             printf( "%d " , node[x][y] ) ; 94         printf( "\n" ) ; 95     } 96 } 97  98  99 int main (  ) {100 //    Init(  ) ;101     input(  ) ;102     sov(  ) ;103     output(  ) ;104 //    fclose( stdin ) ;105 //    fclose( stdout ) ;106     return 0 ;107 }

 

求强连通分量