题意:a喜欢b,b喜欢c,则a喜欢c 现在问被所有其他的牛喜欢的牛的只数
tarjan求强连通分量并缩点 判断缩点后的度数,度数为0的点超过一个则答案为0
Source Code
- Source Code
#include <iostream> #include "stdio.h" #include "stdlib.h" #include "string.h" #include "math.h" #include <algorithm> #include "vector" using namespace std; #define N 10002 int outdgree[N]={0},cnt,ans,answer,low[N],dfn[N],instack[N],stac[N], belong[N],n,Bcnt,times,pos,a[N*5],b[N*5]; vector <int> vec[N]; void tarjan_scc(int v) { int w,l=vec[v].size(); times++; low[v]=dfn[v]=times; instack[v]=1; stac[++pos]=v; for(int i=0;i<l;i++) { w=vec[v][i]; if(!dfn[w]){ tarjan_scc(w); low[v]=min(low[w],low[v]); } else if(instack[w]) low[v]=min(low[v],dfn[w]); } if(dfn[v]==low[v]){ Bcnt++; do{ w=stac[pos--]; instack[w]=0; belong[w]=Bcnt; }while(w!=v); } } void init() { memset( low, 0 ,sizeof(low)); memset( dfn, 0 ,sizeof(dfn)); memset( instack, 0, sizeof(instack)); memset( stac,0, sizeof(stac)); memset( belong,0, sizeof(belong)); memset(outdgree,0,sizeof(outdgree)); Bcnt=0;times=0;pos=0;answer=0;cnt=0; } int main(void) { int m; //freopen("2186","r",stdin); while(cin>>n>>m) { init(); for(int i=1;i<=m;i++) { cin>>a[i]>>b[i]; vec[b[i]].push_back(a[i]); } for(int i=1;i<=n;i++) { if(!dfn[i]) tarjan_scc(i); } for(int i=1;i<=m;i++) if(belong[a[i]]!=belong[b[i]]) outdgree[belong[a[i]]]++; for(int i=1;i<=Bcnt;i++) if(outdgree[i]==0) { cnt++; ans=i; } if(cnt>1) cout<<0<<endl; else if(cnt==0) cout<<0<<endl; else{ for(int i=1;i<=n;i++) if(belong[i]==ans) answer++; cout<<answer<<endl; } for(int i=0;i<=n;i++) vec[i].clear(); } }