BZOJ1051
强连通。
若只存在一个强连通分量出度为0(树根,万人敬仰),答案就是这个强连通的节点数。
若存在多个,答案即为0
#include<cstdio>
#include<cstdlib>
#include<cstring>
#define min(x,y) (x<y?x:y)
struct
mod{
int
x,y,next;};
mod q[50015];
int
len=0,id=0,tp=0,num=0;
int
first[10015];
int
dfn[10015];
int
low[10015];
int
home[10015];
int
size[10015];
bool
vis[10015];
int
sta[10015];
int
in[10015];
int
out[10015];
void
ins(
int
x,
int
y)
{
len++;
q[len].x=x;
q[len].y=y;
q[len].next=first[x];
first[x]=len;
}
void
dfs(
int
x)
{
dfn[x]=low[x]=++id;
vis[x]=
true
;
sta[++tp]=x;
for
(
int
i=first[x];i!=0;i=q[i].next)
{
int
y=q[i].y;
if
(dfn[y]==-1)
{
dfs(y);
low[x]=min(low[x],low[y]);
}
else
{
if
(vis[y]==
true
)
low[x]=min(low[x],dfn[y]);
}
}
if
(low[x]==dfn[x])
{
num++;
while
(1)
{
int
i=sta[tp--];
vis[i]=
false
;
home[i]=num;
size[num]++;
if
(i==x)
break
;
}
}
}
int
main()
{
int
n,m;
scanf
(
"%d%d"
,&n,&m);
for
(
int
i=1;i<=m;i++)
{
int
x,y;
scanf
(
"%d%d"
,&x,&y);
ins(x,y);
}
memset
(dfn,-1,
sizeof
(dfn));
memset
(low,0,
sizeof
(low));
memset
(size,0,
sizeof
(size));
for
(
int
i=1;i<=n;i++)
if
(dfn[i]==-1)
dfs(i);
int
ans=0;
for
(
int
i=1;i<=m;i++)
{
if
(home[q[i].x]!=home[q[i].y])
in[home[q[i].y]]++,out[home[q[i].x]]++;
}
for
(
int
i=1;i<=num;i++)
{
if
(out[i]==0&&in[i]!=0)
ans+=size[i];
}
printf
(
"%d\n"
,ans);
}