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
Sample Output
1
HINT
100%的数据N<=10000,M<=50000
这道题首先对原图求一遍强连通分量,然后找其中出度为0的强连通分量,如果有多个,则答案为0(因为任意两个出度为0的强连通分量中的牛一定不会互相喜欢),如果只有一个,则答案为这个强连通分量中的节点数,下面是程序:
#include<stdio.h>
#include<iostream>
using namespace std;
const int N=10005;
struct stack{
int t,a[N];
void clear(){
t=0;
}
bool empty(){
return !t;
}
void push(int x){
a[t++]=x;
}
void pop(){
--t;
}
int top(){
return a[t-1];
}
}t;
struct edge{
int v,next;
}e[N*5];
int head[N],pre[N],low[N],scc[N],sum[N],num[N],dfs_clock,s,k;
void add(int u,int v){
++k;
e[k].v=v;
e[k].next=head[u];
head[u]=k;
}
void dfs(int u){
pre[u]=low[u]=++dfs_clock;
t.push(u);
int i,v;
for(i=head[u];i;i=e[i].next){
v=e[i].v;
if(!pre[v]){
dfs(v);
low[u]=min(low[u],low[v]);
}
else{
if(!scc[v]){
low[u]=min(low[u],pre[v]);
}
}
}
if(low[u]==pre[u]){
++s;
do{
v=t.top();
t.pop();
scc[v]=s;
}while(u!=v);
}
}
int main(){
int n,m,i,j,ans=-1;
scanf("%d%d",&n,&m);
while(m--){
scanf("%d%d",&i,&j);
add(i,j);
}
for(i=1;i<=n;i++){
if(!pre[i]){
dfs(i);
}
}
for(i=1;i<=n;i++){
num[scc[i]]++;
for(j=head[i];j;j=e[j].next){
if(scc[i]!=scc[e[j].v]){
sum[scc[i]]++;
}
}
}
for(i=1;i<=s;i++){
if(!sum[i]){
if(ans==-1){
ans=num[i];
}
else{
ans=0;
break;
}
}
}
printf("%d\n",ans);
return 0;
}