Description
每一头牛的愿望就是变成一头最受欢迎的牛。现在有N头牛,给你M对整数(A,B),表示牛A认为牛B受欢迎。 这种关系是具有传递性的,如果A认为B受欢迎,B认为C受欢迎,那么牛A也认为牛C受欢迎。你的任务是求出有多少头牛被所有的牛认为是受欢迎的。
Input
第一行两个数N,M。 接下来M行,每行两个数A,B,意思是A认为B是受欢迎的(给出的信息有可能重复,即有可能出现多个A,B)
Output
一个数,即有多少头牛被所有的牛认为是受欢迎的。
Sample Input
3 3
1 2
2 1
2 3
1 2
2 1
2 3
Sample Output
1
HINT
100%的数据N<=10000,M<=50000
tarjan+缩点,最后答案为出度为0的sum,如果有多个出度为0的点,那么答案为0.
//Serene
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
using namespace std;
const int maxn=1e4+10,maxm=5e4+10;
int n,m;
bool cd[maxn];
int aa,ff;char cc;
int read() {
aa=0;cc=getchar();ff=1;
while(cc<'0'||cc>'9') {
if(cc=='-') ff=-1;
cc=getchar();
}
while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
return aa*ff;
}
int fir[maxn],nxt[maxm],to[maxm],e=0;
void add(int x,int y) {
to[++e]=y;nxt[e]=fir[x];fir[x]=e;
}
int zz[maxn],id[maxn],top[maxn],d=0,t=0;
bool vis[maxn],inz[maxn];
int xd[maxn],sum[maxn],tot;
void tj(int pos) {
id[pos]=top[pos]=++d;
vis[pos]=inz[pos]=1;
zz[++t]=pos; int z;
for(int y=fir[pos];y;y=nxt[y]) {
z=to[y];
if(vis[z]) {
if(inz[z]) top[pos]=min(top[pos],top[z]);
continue;
}
tj(z); top[pos]=min(top[pos],top[z]);
}
if(top[pos]==id[pos]) {
sum[++tot]=0;
while(t) {
xd[zz[t]]=tot;
inz[zz[t]]=0;
sum[tot]++;
t--;
if(zz[t+1]==pos) break;
}
}
}
int main() {
n=read();m=read();
int x,y,ans=0;
for(int i=1;i<=m;++i) {
x=read();y=read();
add(x,y);
}
tj(1);
for(int i=1;i<=n;++i) for(int y=fir[i];y;y=nxt[y]) {
if(xd[to[y]]!=xd[i]) cd[xd[i]]=1;
}
for(int i=1;i<=tot;++i) if(!cd[i]){
if(ans) {
ans=0;
break;
}
ans=sum[i];
}
printf("%d",ans);
return 0;
}