LA 4287 Proving Equivalences (強連通)

#include
#include<cstring>
#include<string>
#include<cstdio>
#include<stdio.h>
#include<algorithm>
#include<cmath>
#include<set>
#include<map>
#include<queue>
#include<vector>
using namespace std;




#define inf 0x3f3f3f3f
#define eps 1e-9
#define mod 1000000007
#define FOR(i,s,t) for(int i = s; i < t; ++i )
#define REP(i,s,t) for( int i = s; i <= t; ++i )
#define LL long long
#define ULL unsigned long long
#define pii pair<int,int>
#define MP make_pair
#define lson id << 1 , l , m
#define rson id << 1 | 1 , m + 1 , r 
#define maxn ( 20000+10 )
#define maxe ( 50000+10 )




int sccno[maxn], S[maxn], low[maxn], pre[maxn];
vector<int> G[maxn];
int scc_cnt, s_cnt, Clock;


void dfs ( int u  ) {
low[u] = pre[u] = ++Clock;
S[s_cnt++] = u;
for( int i = 0; i < G[u].size(); ++i ) {
int v = G[u][i];
if( !pre[v] ) {
dfs( v );
low[u] = min ( low[u], low[v] );
}
else if( !sccno[v] ) {
low[u] = min ( low[u], pre[v] );
}
}
if( low[u] == pre[u] ) {
scc_cnt++;
while( 1 ) {
int v = S[--s_cnt];
sccno[v] = scc_cnt;
if( v == u ) break;
}
}
}


void find_scc ( int n ) {
memset( sccno, 0, sizeof( sccno ) );
memset( low, 0, sizeof( low ) ) ;
memset( pre, 0, sizeof( pre ) );
scc_cnt = s_cnt = Clock = 0;
for( int i = 0 ; i< n; ++i ) {
if( !sccno[i] ) dfs( i ) ;
}
}


int in[maxn], out[maxn];
int main ( ) {
int T;
scanf("%d", &T );
while( T-- ) {
int n, m;


scanf("%d%d", &n, &m ) ;
int u, v;
for( int i = 0; i < n; ++i ) G[i].clear();
for( int i = 0; i < m; ++i ){
scanf("%d%d", &u, &v );
--u,--v;
G[u].push_back( v );
}


find_scc( n );


for( int i = 1; i <= scc_cnt ; ++i ) in[i] = out[i] = 1;
for( int i = 0; i < n; ++i ) {
for( int j = 0; j < G[i].size(); ++j ){ 
if( sccno[i] != sccno[G[i][j]] )
in[sccno[G[i][j]]] = out[sccno[i]] = 0;
}
}


int a = 0, ans = 0, b = 0;
for( int i = 1; i <= scc_cnt; ++i ) {
if( in[i] ) a++;
if( out[i] ) b++;
}
ans = max( a, b );
//cout<<a<<endl<<b<<endl;
if( scc_cnt ==1 ) ans = 0;
printf("%d\n", ans );
}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章