描述
给出一个有向图,求该图的强连通分量的个数。
输入描述
多测试用例,每个测试用例:
第一行给出顶点数 n ( 1 ≤ n ≤ 1000 )
第二行给出边数 e ( 0 ≤ e ≤ 100000 )
第三行开始,共 e 行,每行两个正整数 a b,表示从顶点 a 发出一条弧到顶点 b 。
输出描述
每个测试用例一行结果,一个正整数:该有向图的强连通分量的个数。
用例输入 1
8 11 1 2 2 3 3 4 4 1 5 6 6 7 7 8 8 5 4 2 5 7 2 5
用例输出 1
2
#include<iostream>
#include<stack>
#include<memory.h>
using namespace std;
int n;
int G[1010][1010];
int Time,sum;
int beg[1010],low[1010];
stack<int> S;
int in_stack[1010];
void DFS(int v){
beg[v]=low[v]=++Time; //初始化始末
S.push(v); //进栈
in_stack[v]=1; //标记进栈
for(int i=1;i<=n;i++){
if(G[v][i]==1){
if(beg[i]==0){
DFS(i);
low[v]=min(low[v],low[i]);
}else if(in_stack[i]==1){
low[v]=min(low[v],low[i]);
}
}
}
if(beg[v]==low[v]){
int t;
sum++;
do{
t=S.top();
S.pop();
in_stack[t]=0;
}while(t!=v);
}
}
int main(){
int a,b,m;
while(scanf("%d",&n)!=EOF){
scanf("%d",&m);
memset(G,0,sizeof(G));
for(int i=1;i<=m;i++){
scanf("%d%d",&a,&b);
G[a][b]=1;
}
Time=sum=0;
memset(beg,0,sizeof(beg));
memset(low,0,sizeof(low));
memset(in_stack,0,sizeof(in_stack));
for(int z=1;z<=n;z++){
if(beg[z]==0){
DFS(z);
}
}
printf("%d\n",sum);
}
return 0;
}