Tarjan算法
来源:互联网 发布:王者荣耀mvp新算法 编辑:程序博客网 时间:2024/05/17 02:05
#include<stdio.h>#include<string.h>#include<vector>#include<stack>using namespace std;const int maxn = 105;int n,m;int dfs_clock,scc_cnt;int low[maxn],dfn[maxn],sccno[maxn]; //sccno[i]为i所在的SCC编号stack<int>S;vector<int>map[maxn];void tarjan( int u, int fa ){ low[u] = dfn[u] = ++dfs_clock;S.push(u); for( int i = 0; i < map[u].size(); i ++ ) { int v = map[u][i]; if( !dfn[v] ) { tarjan( v,u ); low[u] = low[u] <= low[v] ? low[u]:low[v]; //用后代low更新自己 } else if( !sccno[v] ) //用反向边更新自己{ low[u] = low[u] <= dfn[v] ? low[u]:dfn[v];} }if( low[u] == dfn[u] ){scc_cnt ++;for(;;){int x = S.top(); S.pop();sccno[x] = scc_cnt;if( x == u )break;}}}void find_scc(){dfs_clock = scc_cnt = 0;while( !S.empty() )S.pop(); memset( low,0,sizeof(low) ); memset( dfn,0,sizeof(dfn) );memset( sccno,0,sizeof(sccno) );for( int i = 0; i < n; i ++ ){if( !dfn[i] )tarjan( i,-1 );}}int main(){//freopen( "data.txt","r",stdin ); int u,v;while( scanf("%d%d",&n,&m) == 2 ){for( int i = 0; i < n; i ++ )map[i].clear();for( int i = 1; i <= m; i ++ ){scanf("%d%d",&u,&v);map[u].push_back(v);}find_scc();printf("%d\n",scc_cnt);}return 0;}