Tarjan求调

P8436 【模板】边双连通分量

ZVitality @ 2023-06-02 14:00:35

#include <bits/stdc++.h>
using namespace std;

const int _ = 2e6 + 5;

struct Edge { int v , w , nxt ; } e[_*2];
int head[_] , ecnt;
void Add( int u , int v , int w = 1 ) { e[ ++ecnt ] = Edge{ v , w , head[ u ] } ; head[ u ] = ecnt ; }

int n , m;

int dfn[_] , low[_] , cnt = 1;
vector< int > DCC[_];
int be[_] , c[_] , dcc;

void Tarjan( int x , int p ) {
  dfn[ x ] = low[ x ] = ++cnt;
  for( int i = head[ x ] ; i ; i = e[ i ].nxt ) {
    int y = e[ i ].v;
    if( !dfn[ y ] ) {
      Tarjan( y , i );
      low[ x ] = min( low[ x ] , low[ y ] );
      if( low[ y ] > dfn[ x ] ) {
        c[ i ] = c[ i ^ 1 ] = 1;
      }
    } else if( i != ( p ^ 1 ) ) {
      low[ x ] = min( low[ x ] , dfn[ y ] );
    }
  }
}

void DFS( int x ) {
  be[ x ] = dcc;
  DCC[ dcc ].push_back( x );
  for( int i = head[ x ] ; i ; i = e[ i ].nxt ) {
    int y = e[ i ].v;
    if( !be[ y ] && !c[ i ] ) {
      DFS( y );
    }
  }
}

int main() {
  int n , m;
  cin >> n >> m;
  for( int i = 1 , u , v ; i <= m ; i++ ) {
    cin >> u >> v;
    Add( u , v );
    Add( v , u );
  }
  for( int i = 1 ; i <= n ; i++ ) {
    if( !dfn[ i ] ) {
      Tarjan( i , 0 );
    }
  }
  for( int i = 1 ; i <= n ; i++ ) {
    if( !be[ i ] ) {
      dcc++;
      DFS( i );
    }
  }
  cout << dcc << '\n';
  for( int i = 1 ; i <= dcc ; i++ ) {
    cout << DCC[ i ].size() << ' ';
    for( int j = 0 ; j < DCC[ i ].size() ; j++ ) {
      cout << DCC[ i ][ j ] << " \n"[ j == DCC[ i ].size() - 1 ];
    }
  }
  return 0;
}

by Ranya @ 2023-06-02 15:24:26

@zzq_666 初始化ecnt=1


by ZVitality @ 2023-06-02 18:32:45

@Ranya 过了,谢谢!


|