#include<iostream> #include<string> #include<string.h> #include<algorithm> #define N 10001 #define M 50005 using namespace std; bool istack[N]; int head[N],dfn[N],low[N],stack[N],belong[N],out[N]; int n,m,res,index,num,top; typedef struct str { int to; int next; }Node; Node node[M]; void init() { memset(head,-1,sizeof(head)); memset(dfn,0,sizeof(dfn)); memset(low,0,sizeof(low)); memset(out,0,sizeof(out)); memset(belong ,0,sizeof(belong)); memset(istack,false,sizeof(istack)); memset(stack,0,sizeof(stack)); res=top=num=0; index=1; } void dfs(int i) { dfn[i]=low[i]=index++; istack[i]=true; stack[top++]=i; for(int j=head[i];j!=-1;j=node[j].next) { int v=node[j].to; if(!dfn[v]) { dfs(v); low[i]=min(low[i],low[v]); } else if(istack[v]) low[i]=min(dfn[v],low[i]); } int u; if(dfn[i]==low[i]) { res++; do { u=stack[--top]; belong[u]=res; istack[u]=false; }while(i!=u); } } void tarjan() { for(int i=1;i<=n;++i) if(!dfn[i]) dfs(i); } void solve() { for(int i=1;i<=n;++i) for(int j=head[i];j!=-1;j=node[j].next) if(belong[i]!=belong[node[j].to]) out[belong[i]]++; int cnt=0,p; for(int i=1;i<=res;++i) if(!out[i]) { cnt++; p=i; } int sum=0; if(cnt==1) { for(int i=1;i<=n;++i) if(belong[i]==p) sum++; cout<<sum<<endl; } else cout<<"0"<<endl; } int main() { while(cin>>n>>m) { init(); for(int i=0;i!=m;++i) { int a,b; cin>>a>>b; node[num].to=b; node[num].next=head[a]; head[a]=num++; } tarjan(); solve(); }return 0; }
题意:给你一些关系a,b例如:a,b表示a牛认为b牛受欢迎,输出所有的大家都公认受欢迎牛(图中任意一个顶点至少有一条可以到达该点的路)的个数。
思路:根据给定的关系建立有向图,求有向图中的强连通分量后,缩点找出图中出度为0的点的个数,如果有超过或等于两个强连通分量的出度为0,则说明不存在受欢迎的牛。