Description
每一头牛的愿望就是变成一头最受欢迎的牛。现在有N头牛,给你M对整数(A,B),表示牛A认为牛B受欢迎。 这种关系是具有传递性的,如果A认为B受欢迎,B认为C受欢迎,那么牛A也认为牛C受欢迎。你的任务是求出有多少头牛被所有的牛认为是受欢迎的。
***注意要被所有的牛支持****
解:缩点之后求根那个点的大小
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
#include<vector>
#define mem(a,b) memset(a,b,sizeof a)
#define en '\n'
#define maxn 100005
using namespace std;
typedef long long ll;
template<class T>void rd(T &x)
{
x=0;int f=0;char ch=getchar();
while(ch<'0'||ch>'9') {f|=(ch=='-');ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
x=f?-x:x;
return;
}
const int inf =1<<29;
int head[maxn];
int n,m,tot;
int cnt=0;
int low[maxn],dfn[maxn],num,sta[maxn],top,ins[maxn],sum=0;
int cost[maxn],c[maxn],c_num[maxn];
int tot2;
int ans_sum[maxn];
int st[maxn],ed[maxn],sz[maxn];
bool vis[maxn];
int rudu[maxn],chudu[maxn],val[maxn],mx,ren;
struct node{
int v,nxt;
}edge[maxn<<3];
void add(int x,int y){
edge[++tot]=node{y,head[x]};head[x]=tot;
}
void tarjan(int x){
dfn[x]=low[x]=++num;
sta[++top]=x,
ins[x]=1;
for(int i=head[x];i;i=edge[i].nxt){
if(!dfn[edge[i].v]){
tarjan(edge[i].v);
low[x]=min(low[x],low[edge[i].v]);
}else if(ins[edge[i].v])low[x]=min(low[x],dfn[edge[i].v]);
}
if(dfn[x]==low[x]){
cnt++;
int y;
do{
y=sta[top--];ins[y]=0;
c[y]=cnt;
c_num[cnt]+=1;
}while(x!=y);
}
}
vector<int>vec[maxn];
void dfs(int x,int fa){
val[x]=sz[x];
for(int i=0;i<vec[x].size();i++){
int y=vec[x][i];if(y==fa)continue;
dfs(y,x);
val[x]+=val[y];
}
}
signed main()
{
#ifdef local
freopen("input2.txt","r",stdin);
#endif
cin>>n>>m;
mem(head,0);
tot=tot2=num=cnt=0;
mem(dfn,0);
mem(chudu,0);
mem(rudu,0);
for(int i=0;i<m;i++){
int x,y;scanf("%d%d",&x,&y);st[i]=x;ed[i]=y;add(x,y);
}
for(int i=1;i<=n;i++){
if(!dfn[i])tarjan(i);
}
#define pb push_back
for(int i=1;i<=n;i++)sz[c[i]]+=1;
for(int i=0;i<m;i++){
if(c[st[i]]!=c[ed[i]]){
chudu[c[st[i]]]+=1;
vec[c[ed[i]]].pb(c[st[i]]);
}
}
int ttt=0;
for(int i=1;i<=cnt ;i++){
if(!chudu[i]){
ttt+=1;
dfs(i,0);
ren=sz[i];
}
}
if(ttt>1){
cout<<0<<en;
}else{
cout<<ren<<en;
}
return 0;
}