题意:有N头牛 每一头牛都梦想着成为popular cow,(但这是不可能滴) 有m组仰慕的关系,仰慕有传递性比如说A觉得B
是popular and B thinks C is popular, then A thinks C is popalur also;
现在问有多少头牛是会被其他牛都仰慕。思路:求强连通分量,缩成点 点内的头当然是相互仰慕的咯!! 然后求新的图 的出度 出度也0的点就会被所有牛仰慕算出出度为0的强连通分量里点的个数就OK了,注意 可能有多个出度为0的点,这时输出0 ;
#include<cstdio> #include<cstring> #include<map> #include<vector> #include<cmath> #include<cstdlib> #include<queue> #include <iomanip> #include<iostream> #include<algorithm> using namespace std ; const int N= 11111 ; const int M= 55555 ; struct node { int u ,v,next; }edge[M] ; int head[N],low[N],dfn[N],vist[N],stack[N],belong[N],out[N] ; int top ,sum,cnt,dep ; void add(int u ,int v) { edge[top].u=u; edge[top].v=v; edge[top].next=head[u]; head[u]=top++; } void tarjan(int u ) { low[u]=dfn[u]=++dep; stack[cnt++]=u; vist[u]=1; for(int i = head[u] ; i!=-1 ; i=edge[i].next) { int v= edge[i].v ; if(!dfn[v]) { tarjan(v) ; low[u] = min( low[u] , low[v] ) ; }else if(vist[v]) low[u] = min( low[u] , dfn[v] ); } if(low[u] == dfn[u]) { int x; sum++ ; do { x=stack[--cnt] ; vist[x] = 0 ; belong[x]=sum; }while(x!=u) ; } } int main() { int n,m,u,v ; while(~scanf("%d%d",&n,&m)) { top = sum = dep = cnt = 0; memset(head,-1,sizeof(head)); memset(out,0,sizeof(out)); memset(belong,0,sizeof(belong)); memset(low,0,sizeof(low)) ; memset(dfn,0,sizeof(dfn)) ; memset(vist,0,sizeof(vist)) ; for(int i = 1 ; i <= m ; i++) { scanf("%d%d",&u,&v) ; add(u,v); } for(int i = 1 ; i <= n ; i++) if(!dfn[i]) tarjan(i) ; // printf("%d* ",sum); for(int i = 1 ; i <= n ; i++) for(int j = head[i] ; j!=-1; j=edge[j].next) { int v = edge[j].v ; if(belong[i] != belong[v]) { out[belong[i]]++; } } int flag = 0 , k ; for(int i = 1 ; i <= sum ; i++) if(out[i] == 0 ) { k=i ; flag++; if(flag > 1) break ; } if( flag > 1 ) { printf("0\n"); } else { int ans = 0 ; for(int i = 1 ; i <= n ; i++) if(belong[i] == k) ans++; printf("%d\n",ans); } } return 0; }