题目链接:http://poj.org/problem?id=2186
题解:强连通分量缩点,Your task is to compute the number of cows that are considered popular by every other cow. 只需计算出度为0的点数,如果出度为0的点数大于一,输出0(不符合题意),否则输出出度为0的强连通分量的点数。
#include <stdio.h> #include <string.h> #define MAXN 10001 struct node { int to,next; }edge[50001]; int belong[MAXN],num[MAXN],outdegree[MAXN]; int head[MAXN],instack[MAXN],low[MAXN],dfn[MAXN]; int stack[MAXN],tot,Dindex,top,Bcnt,n; void Init() {//初始化 int i; tot=0,top=0,Dindex=0,Bcnt=0; memset(head,-1,sizeof(head)); memset(instack,0,sizeof(instack)); memset(dfn,0,sizeof(dfn)); memset(low,0,sizeof(low)); memset(belong,0,sizeof(belong)); memset(num,0,sizeof(num)); // memset(indegree,0,sizeof(indegree)); memset(outdegree,0,sizeof(outdegree)); } void addEdge(int from,int to) { edge[tot].to=to; edge[tot].next=head[from]; head[from]=tot++; } int Scan() { char ch; int ret=0; while((ch=getchar())<'0'||ch>'9'); while(ch>='0'&&ch<='9') { ret=ret*10+(ch-'0'); ch=getchar(); } return ret; } void Tarjan(int x) { int i,u,v; dfn[x]=low[x]=++Dindex;//时间戳 stack[top++]=x; instack[x]=1; for(i=head[x];i!=-1;i=edge[i].next) { u=edge[i].to; if(!dfn[u]) { Tarjan(u); low[x]=low[x]>low[u]?low[u]:low[x]; } else if(instack[u]&&low[x]>dfn[u]) low[x]=dfn[u]; } if(low[x]==dfn[x]) { Bcnt++; do { v=stack[--top]; instack[v]=0; belong[v]=Bcnt; num[Bcnt]++;//保存该强连通分量的点数 } while (v!=x); } } int main() { int m,i,j,x; while(scanf("%d %d",&n,&m)!=EOF) { Init(); while(m--) { i=Scan(); j=Scan(); addEdge(i,j); } for(i=1;i<=n;++i) { if(!dfn[i]) Tarjan(i); } for(i=1;i<=n;++i) { for(j=head[i];j!=-1;j=edge[j].next) { x=edge[j].to; if(belong[i]!=belong[x]) //不在同一个连通分量的点 { outdegree[belong[i]]++; //indegree[belong[x]]++; } } } x=0; for(i=1;i<=Bcnt;++i) { if(outdegree[i]==0) { x++; j=i; } } if(x==1) printf("%d\n",num[j]); else printf("0\n"); } return 0; }