这个坑有点大,刚学oi的蒟蒻其实稍微有点没看懂targin的原理,但是在深搜中,强连通分量一定在同一个子树里肯定是对的,那么接下来直接附上代码吧(之后填坑)
#include<stdio.h>
#include<stdlib.h>
int vis1[100001]={0},nxt[100001]={0},head[100001]={0},low[100001]={0},st[100001]={0},dfn[100001]={0};
int to[100001]={0},co[100001]={0},numcol[100001]={0};
int n,m,num=0,tmp=0,top=0,col=0;
int min(int x,int y)
{
if(x>y)
return y;
else return x;
}
int add(int x,int y)
{
tmp++;
nxt[tmp]=head[x];
to[tmp]=y;
head[x]=tmp;
return 0;
}
int targin(int u)
{
int i,v;
num++;vis1[u]=1;
dfn[u]=num;low[u]=num;
top++;
st[top]=u;
for(i=head[u];i;i=nxt[i])
{
v=to[i];
if(dfn[v]==0)
{
targin(v);
low[u]=min(low[u],low[v]);
}
else if(co[v]==0)
low[u]=min(low[u],low[v]);
}
if(low[u]==dfn[u])
{
col++;
co[u]=col;
numcol[col]++;
while(st[top]!=u)
{
co[st[top]]=col;
numcol[col]++;
top--;
}
top--;
}
}
int main()
{
int i,x,y,ans=0;
scanf("%d%d",&n,&m);
for(i=1;i<=m;i++)
{
scanf("%d%d",&x,&y);
add(x,y);
}
for(i=1;i<=n;i++)
if(vis1[i]==0)
targin(i);
for(i=1;i<=col;i++)
if(numcol[i]>=2)
ans++;
printf("%d",ans);
return 0;
}