• 求强连通分量


    还是贴一份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
    " , 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( "
    " ) ;
     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 }
  • 相关阅读:
    File类 文件过滤器
    LinkedList类的基本方法的用法
    Execption异常 手动和自动抛除异常
    Xshell连接Linux慢问题解决办法
    Liunx网络技术管理及进程管理
    Liunx中三种网络模式配置及Xshell连接
    LInux命令英文全称
    Liunx中fstab文件详解
    20190411RAID磁盘阵列及CentOS7系统启动流程
    20190410Linux中磁盘管理及LVM(week2day1)
  • 原文地址:https://www.cnblogs.com/Ateisti/p/5946288.html
Copyright © 2020-2023  润新知