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;}