题意:有N头牛 每一头牛都梦想着成为popular cow,(但这是不可能滴) 有m组仰慕的关系,仰慕有传递性比如说A觉得B
是popular and B thinks C is popular, then A thinks C is popalur also;
现在问有多少头牛是会被其他牛都仰慕。思路:求强连通分量,缩成点 点内的头当然是相互仰慕的咯!! 然后求新的图 的出度 出度也0的点就会被所有牛仰慕算出出度为0的强连通分量里点的个数就OK了,注意 可能有多个出度为0的点,这时输出0 ;
#include<cstdio>
#include<cstring>
#include<map>
#include<vector>
#include<cmath>
#include<cstdlib>
#include<queue>
#include <iomanip>
#include<iostream>
#include<algorithm>
using namespace std ;
const int N= 11111 ;
const int M= 55555 ;
struct node
{
int u ,v,next;
}edge[M] ;
int head[N],low[N],dfn[N],vist[N],stack[N],belong[N],out[N] ;
int top ,sum,cnt,dep ;
void add(int u ,int v)
{
edge[top].u=u;
edge[top].v=v;
edge[top].next=head[u];
head[u]=top++;
}
void tarjan(int u )
{
low[u]=dfn[u]=++dep;
stack[cnt++]=u;
vist[u]=1;
for(int i = head[u] ; i!=-1 ; i=edge[i].next)
{
int v= edge[i].v ;
if(!dfn[v])
{
tarjan(v) ;
low[u] = min( low[u] , low[v] ) ;
}else if(vist[v])
low[u] = min( low[u] , dfn[v] );
}
if(low[u] == dfn[u])
{
int x;
sum++ ;
do
{
x=stack[--cnt] ;
vist[x] = 0 ;
belong[x]=sum;
}while(x!=u) ;
}
}
int main()
{
int n,m,u,v ;
while(~scanf("%d%d",&n,&m))
{
top = sum = dep = cnt = 0;
memset(head,-1,sizeof(head));
memset(out,0,sizeof(out));
memset(belong,0,sizeof(belong));
memset(low,0,sizeof(low)) ;
memset(dfn,0,sizeof(dfn)) ;
memset(vist,0,sizeof(vist)) ;
for(int i = 1 ; i <= m ; i++)
{
scanf("%d%d",&u,&v) ;
add(u,v);
}
for(int i = 1 ; i <= n ; i++)
if(!dfn[i])
tarjan(i) ;
// printf("%d* ",sum);
for(int i = 1 ; i <= n ; i++)
for(int j = head[i] ; j!=-1; j=edge[j].next)
{
int v = edge[j].v ;
if(belong[i] != belong[v])
{
out[belong[i]]++;
}
}
int flag = 0 , k ;
for(int i = 1 ; i <= sum ; i++)
if(out[i] == 0 )
{
k=i ;
flag++;
if(flag > 1)
break ;
}
if( flag > 1 )
{
printf("0\n");
}
else
{
int ans = 0 ;
for(int i = 1 ; i <= n ; i++)
if(belong[i] == k)
ans++;
printf("%d\n",ans);
}
}
return 0;
}