解题思路
首先我们按照题目给出的喜欢关系建一张有向图。
任意一个强连通点对代表的牛都互相喜欢,由此,我们将原图进行缩点,得到一个新的有向无环图,显然一头奶牛能成为一个明星的必要条件有
- 位于出度为0的强连通分量中(若其出度不为0,那么他的出边指向的强连通分量中的牛一定不喜欢它)
- 出度为0的强连通分量只有它所在的唯一一个。(否则,没有妞会成为明星)
所以,将原图缩点的有向无环图图中,如果只有一个出度为0的点,那么这个点所代表的牛都是明星,输出该连通分量中的点数;否则没有牛是明星,输出0.
代码
#include<iostream>
#include<cstdio>
#include<iomanip>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
int n,m,u,v,k,tot,t,top,ans,lyx;
int h[100010],dfn[10010],low[10010],st[10010],c[10010],sum[10010],du[10010];
struct c{
int x,next;
}a[100010];
void add(int x,int y){
a[++k].x=y;
a[k].next=h[x];
h[x]=k;
}
void Tarjan(int x)
{
st[++top]=x;
dfn[x]=low[x]=++t;
for(int i=h[x];i;i=a[i].next)
{
int y=a[i].x;
if(!dfn[y])
{
Tarjan(y);
low[x]=min(low[x],low[y]);
}
else if(!c[y])
low[x]=min(low[x],low[y]);
}
if(dfn[x]==low[x])
{
tot++;
while(st[top+1]!=x)
{
c[st[top]]=tot;
sum[tot]++;
top--;
}
}
}
int main(){
scanf("%d%d",&n,&m);
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);
for(int i=1;i<=n;i++)
{
for(int j=h[i];j;j=a[j].next)
{
int y=a[j].x;
if(c[i]!=c[y])
du[c[i]]++;
}
}
for(int i=1;i<=tot;i++)
{
if(!du[i])
{
lyx++;
ans=sum[i];
}
}
if(lyx==1)
printf("%d",ans);
else printf("0");
}