201509-4 CCF http://118.190.20.162/view.page?gpid=T29
//求一个图的强连通分量 kosaraju算法
#include <bits/stdc++.h> /* Kosaraju求强连通分量邻接矩阵 */
using namespace std;
int mmap[511][511];
int nmap[511][511];
int visited[501];
stack<int>S;
int N;
int DFS1(int v) /* visitedthevnode */
{
visited[v] = 1;
for (int i = 1;i <= N;i++)
if (!visited[i] && mmap[v][i])
DFS1( i );
S.push( v );
return 0;
}
int DFS2( int v )
{
visited[v] = 1;
for (int i = 1;i <= N;i++)
if ( !visited[i] && nmap[v][i] )
{
DFS2( i );
}
return 0;
}
int kosaraju()
{
while (!S.empty())
S.pop();
memset(visited,0,sizeof(visited));
for (int i = 1;i <= N;i++)
if (!visited[i]) DFS1( i );
int t = 0;
memset(visited,0,sizeof(visited));
while (!S.empty())
{
int v = S.top();
S.pop();
if (!visited[v])
{
t++;
DFS2( v );
}
}
return t;
}
int main()
{
int M,s,e;
scanf("%d%d",&N,&M);
memset(mmap,0,sizeof(mmap) );
memset(nmap,0,sizeof(nmap) );
for (int i = 0; i < M; i++)
{
scanf("%d%d",&s,&e);
mmap[s][e] = 1;
nmap[e][s] = 1;
}
printf("%d\n", kosaraju()); /* 输出连通分量个数 */
return 0;
}