//
// main.cpp
// Chapter 1
//
// Created by chengzhi lin on 2018/3/6.
// Copyright © 2018年 lczazu. All rights reserved.
//
#include
#include
#include
#include
#include
#include
#define MAXN 100005
using namespace std;
int _index;
int shelter[ MAXN ] = { 0 };
int polute[ MAXN ] = { 0 };
int vis_time = 0;
int cmp_num = 0;
int low[ MAXN ];
int dfn[ MAXN ];
vector<int> graph[ MAXN ];
vector<int> cmp[ MAXN ];
int in_cmp[ MAXN ];
int out_degree[ MAXN ] = { 0 };
bool in_stack[ MAXN ] = { 0 };
stack<int> sta;
void init( )
{
memset( low, -1, sizeof( low ) );
memset( dfn, -1, sizeof( dfn ) );
}
void tarjan( int x )
{
// cout << "x " << x << endl;
dfn[ x ] = low[ x ] = vis_time++;
in_stack[ x ] = true;
sta.push( x );
for( int i = 0; i < graph[ x ].size( ); ++i )
{
int y = graph[ x ][ i ];
if( dfn[ y ] == -1 )
{
tarjan( y );
low[ x ] = min( low[ x ], low[ y ] );
}
else
{
if( in_stack[ y ] )
{
low[ x ] = min( low[ x ], dfn[ y ] );
}
}
}
if( low[ x ] != dfn[ x ] )
{
return;
}
int y;
do
{
y = sta.top( );
sta.pop( );
in_stack[ y ] = false;
cmp[ cmp_num ].push_back( y );
in_cmp[ y ] = cmp_num;
}while( y != x );
cmp_num++;
}
void add( int a, int b )
{
graph[ a ].push_back( b );
}
void set_degree( )
{
for( int i = 0; i < _index; ++i )
{
int temp = in_cmp[ i ];
for( int j = 0; j < graph[ i ].size( ); ++j )
{
if( in_cmp[ graph[ i ][ j ] ] == temp )
{
continue;
}
++out_degree[ temp ];
}
}
}
int main(int argc, const char * argv[]) {
init( );
for( int i = 0; i < _index; ++i )
{
if( dfn[ i ] == -1 )
{
tarjan( i );
}
}
set_degree( );
return 0;
}