#include<stdio.h>
#include<string.h>
#include<string>
#include<iostream>
#include<algorithm>
#include<vector>
#include<stack>
using namespace std;
const int N=100010;
int isin[N],dfn[N],low[N],bel[N];
vector<int>g[N];
int bnt,cnt;
stack<int>s;
int n,m;
void dfs(int i)
{
dfn[i]=low[i]=++cnt;
isin[i]=1;
s.push(i);
int j;
for(j=0;j<g[i].size();j++)
{
int nn=g[i][j];
if(!dfn[nn]){
dfs(nn);
low[i]=min(low[i],low[nn]);
}
if(isin[nn]==1&&low[nn]<low[i]){//子节点在堆栈中,而且low值小于
low[i]=low[nn];
}
}
if(dfn[i]==low[i]){
bnt++;
do{
j=s.top();
s.pop();
isin[j]=false;
bel[j]=bnt;
}while(j!=i);//这里不要改成while(i!=j)虽然我也不知道为啥...
}
}
int solve()
{
memset(low,0,sizeof(low));
memset(bel,-1,sizeof(bel));
memset(dfn,0,sizeof(dfn));
memset(isin,0,sizeof(isin));
cnt=bnt=0;
for(int i=0;i<n;i++)
{
if(!dfn[i])dfs(i);
}
return bnt;
}
int is[N],tongji[N];
int dfs_1()
{
memset(is,0,sizeof(is));
for(int i=0;i<n;i++)
{
for(int j=0;j<g[i].size();j++)
{
int v=g[i][j];
if(bel[i]!=bel[v]){
is[bel[i]]=1;
}
}
}
int cnt=0;
int no=-1;
//cout<<bnt<<endl;
for(int i=1;i<=bnt;i++){
if(is[i]==0){
cnt++;
no=i;
}
}
//cout<<cnt<<" "<<no<<endl;
if(cnt==1)
return no;
else
return -1;
}
int main(){
int i,j;
int a,b;
scanf("%d%d",&n,&m);
for(i=0;i<m;i++){
scanf("%d%d",&a,&b);
g[a-1].push_back(b-1);
}
int ret=0;
solve();
memset(tongji,0,sizeof(tongji));
for(i=0;i<n;i++){
tongji[bel[i]]++;
}
ret=dfs_1();
if(ret>0)
printf("%d\n",tongji[ret]);
else
printf("0\n");
return 0;
}
poj 2186 tarjan求强连通分量(模板题)
最新推荐文章于 2022-06-26 23:08:13 发布