Description
Input
Output
Sample Input
3 3 1 2 2 1 2 3
Sample Output
1
Hint
Cow 3 is the only cow of high popularity.
题目大意
对于关系(A,B)表示A牛喜欢B牛
如果(A,B)(B,C)则A牛也喜欢C牛,这是可传递的
求受到所以牛喜欢牛的个数
思路:
用tarjan求强连通分量并缩点,然后看每个点的出度,当且仅当只有一个点的出度为0时候这个点所带表的牛被所有的牛喜欢。
//原来边的个数开小了也会tle
ACcode:
#include <map> #include <queue> #include <cmath> #include <cstdio> #include <cstring> #include <stdlib.h> #include <iostream> #include <algorithm> #define maxn 10005 using namespace std; struct Edge{ int to,next; }my[5*maxn]; int head[maxn],tot; int low[maxn],dfn[maxn],Stack[maxn],Belong[maxn],cdu[maxn],num[maxn]; int index,top,scc; bool instack[maxn]; void add(){ int u,v; scanf("%d%d",&u,&v); my[tot].to=v;my[tot].next=head[u];head[u]=tot++; } void tarjan(int u){ int v; low[u]=dfn[u]=++index; Stack[top++]=u; instack[u]=true; for(int i=head[u];i!=-1;i=my[i].next){ v=my[i].to; if(!dfn[v]){ tarjan(v); if(low[u]>low[v])low[u]=low[v]; } else if(instack[v]&&low[u]>dfn[v])low[u]=dfn[v]; } if(low[u]==dfn[u]){ scc++; do{ v=Stack[--top]; instack[v]=false; Belong[v]=scc; num[scc]++; } while(v!=u); } } void init(){ memset(dfn,0,sizeof(dfn)); memset(instack,false,sizeof(instack)); memset(head,-1,sizeof(head)); memset(num,0,sizeof(num)); memset(cdu,0,sizeof(cdu)); index=scc=top=tot=0; } int main(){ int n,m; while(scanf("%d%d",&n,&m)!=EOF){ init(); while(m--)add(); for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i); int v; for(int i=1;i<=n;++i){ for(int k=head[i];k!=-1;k=my[k].next){ v=my[k].to; if(Belong[i]!=Belong[v]) cdu[Belong[i]]++; } } int flag=0; int ans=0; for(int i=1;i<=scc;i++) if(cdu[i]==0){ flag++; ans=num[i]; } if(flag!=1) ans=0; printf("%d\n",ans); } return 0; }