poj2816 Popular Cows

来源:互联网 发布:qq网名生成器软件 编辑:程序博客网 时间:2024/06/05 05:00

链接:http://poj.org/problem?id=2186

题意:农场有一群奶牛。如果奶牛A认为奶牛Bpopular,奶牛B认为奶牛Cpopular,则奶牛A也认为奶牛Cpopular。

求,有没有这样被所有人都认为popular的奶牛?


有向图,先求强连通分量,再对每个分量缩点,求每个缩点的出度。

如果缩点中有且仅有一个出度为0,则该缩点内的所有奶牛均为被每一头奶牛受欢迎的。

如果不止一个缩点的出度为0,则不存在这样的奶牛。例如下面这组数据:

3 2
2 1
2 3

输出:0

#include<cstdio>#include<cstring>#define MAXN 10005#define MAXE 50005using namespace std;int n,m;struct Edge{  int to;  int next;}edge[MAXE];int head[MAXN],dfn[MAXN],low[MAXN],stack[MAXN],instack[MAXN];int degree[MAXN],belong[MAXN],bans[MAXN];int ecnt,bcnt,index,top;void add(int u,int v){   edge[ecnt].to=v;   edge[ecnt].next=head[u];   head[u]=ecnt++;}void tarjan(int u){   int v,i;   dfn[u]=low[u]=++index;   stack[top++]=u;   instack[u]=1;   for(i=head[u];i!=-1;i=edge[i].next)   {v=edge[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(dfn[u]==low[u])   {   bcnt++;       do   {       v=stack[--top];   instack[v]=0;   belong[v]=bcnt;   bans[bcnt]++;  //缩点   }while(u!=v);   }}int main(){int a,b;while(scanf("%d%d",&n,&m)!=EOF){ecnt=bcnt=0;memset(head,-1,sizeof(head));    for(int i=0;i<m;i++){   scanf("%d%d",&a,&b);   add(a,b);}memset(dfn,0,sizeof(dfn));memset(instack,0,sizeof(instack));memset(belong,0,sizeof(belong));memset(bans,0,sizeof(bans));index=top=0;for(int j=1;j<=n;j++)if(!dfn[j])        tarjan(j);for(int i=1;i<=n;i++){   for(int j=head[i];j!=-1;j=edge[j].next)   {   if(belong[i]!=belong[edge[j].to])//如果两个点不在一个连通分量,父节点出度加加degree[belong[i]]++;   }}int pos,num=0;for(int i=1;i<=bcnt;i++)if(degree[i]==0){pos=i;    num++;}if(num==1)printf("%d\n",bans[pos]);elseprintf("%d\n",0);}return 0;}


0 0
原创粉丝点击