[bzoj1051][HAOI2006]受欢迎的牛【tarjan】
【题目链接】
http://www.lydsy.com/JudgeOnline/problem.php?id=1051
【题解】
tarjan缩点,如果只有一个块出度为0,那么那个块的所有点就是答案,否则无解
/* --------------
user Vanisher
problem bzoj-1051
----------------*/
# include <bits/stdc++.h>
# define ll long long
# define N 100100
using namespace std;
int read(){
int tmp=0, fh=1; char ch=getchar();
while (ch<'0'||ch>'9'){if (ch=='-') fh=-1; ch=getchar();}
while (ch>='0'&&ch<='9'){tmp=tmp*10+ch-'0'; ch=getchar();}
return tmp*fh;
}
struct node{
int data,next;
}e[N];
int use[N],low[N],dfn[N],st[N],place,ti,head[N],size[N],p[N],top,num,n,m,tag[N],u[N],v[N];
void build(int u, int v){
e[++place].data=v; e[place].next=head[u]; head[u]=place;
}
void tarjan(int x){
use[x]=1; low[x]=dfn[x]=++ti; st[++top]=x;
for (int ed=head[x]; ed!=0; ed=e[ed].next){
if (use[e[ed].data]==0){
tarjan(e[ed].data);
low[x]=min(low[x],low[e[ed].data]);
}
if (use[e[ed].data]==1)
low[x]=min(low[x],dfn[e[ed].data]);
}
if (low[x]==dfn[x]){
num++;
while (st[top]!=x){
size[num]++;
p[st[top]]=num;
use[st[top--]]=2;
}
p[st[top]]=num; use[st[top--]]=2;
size[num]++;
}
}
int main(){
n=read(), m=read();
for (int i=1; i<=m; i++){
u[i]=read(), v[i]=read();
build(u[i],v[i]);
}
for (int i=1; i<=n; i++)
if (use[i]==0) tarjan(i);
int cnt=0, id;
for (int i=1; i<=m; i++)
if (p[u[i]]!=p[v[i]])
tag[p[u[i]]]++;
for (int i=1; i<=num; i++)
if (tag[i]==0) cnt++, id=i;
if (cnt!=1)
printf("0\n");
else printf("%d\n",size[id]);
return 0;
}