题意:
有N(N<=10000)头牛,每头牛都想成为most poluler的牛,给出M(M<=50000)个关系,如(1,2)代表1欢迎2,关系可以传递,但是不可以相互,即1欢迎2不代表2欢迎1,但是如果2也欢迎3那么1也欢迎3.给出N,M和M个欢迎关系,求被所有牛都欢迎的牛的数量。
/*
tarjan缩点后,统计每个所点的出度,当有且只有一个出度为0的缩点是,
答案即为这个缩点所包含的点的数量,否则答案为0
*/
#include<cstdio>
#include<iostream>
#include<cstring>
#include<vector>
#include<stack>
#define M 10010
using namespace std;
int low[M],num[M],belong[M],vis[M],instack[M],in[M],out[M],sum[M],indexx,cnt,n,m;
vector<int> grap[M];
stack<int> s;
void tarjan(int v)
{
low[v]=num[v]=++indexx;
s.push(v);
vis[v]=;
instack[v]=;
for(int i=;i<grap[v].size();i++)
{
int w=grap[v][i];
if(!vis[w])
{
tarjan(w);
low[v]=min(low[v],low[w]);
}
else if(instack[w])
low[v]=min(low[v],num[w]);
}
int u;
if(low[v]==num[v])
{
++cnt;
do
{
u=s.top();
s.pop();
belong[u]=cnt;
sum[cnt]++;
instack[u]=;
}
while(u!=v);
}
}
void work()
{
for(int i=;i<=m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
grap[y].push_back(x);
}
for(int i=;i<=n;i++)
if(!vis[i])
tarjan(i);
for(int i=;i<=n;i++)
for(int j=;j<grap[i].size();j++)
if(belong[i]!=belong[grap[i][j]])
{
in[belong[i]]++;
out[belong[grap[i][j]]]++;
}
int tot=,p;
for(int i=;i<=cnt;i++)
if(!out[i])
{
tot++;
p=i;
}
if(tot==)printf("%d\n",sum[p]);
else printf("0\n");
}
int main()
{
while(scanf("%d%d",&n,&m)==)
{
work();
memset(low,,sizeof(low));
memset(num,,sizeof(num));
memset(belong,,sizeof(belong));
memset(vis,,sizeof(vis));
memset(instack,,sizeof(instack));
memset(in,,sizeof(in));
memset(out,,sizeof(out));
memset(sum,,sizeof(sum));
for(int i=;i<=n;i++)grap[i].clear();
while(!s.empty())s.pop();
indexx=;
cnt=;
}
}