poj2186 popular cows

来源:互联网 发布:mysql mediumtext 编辑:程序博客网 时间:2024/05/17 14:18

Description

Every cow’s dream is to become the most popular cow in the herd. In a
herd of N (1 <= N <= 10,000) cows, you are given up to M (1 <= M <=
50,000) ordered pairs of the form (A, B) that tell you that cow A
thinks that cow B is popular. Since popularity is transitive, if A
thinks B is popular and B thinks C is popular, then A will also think
that C is popular, even if this is not explicitly specified by an
ordered pair in the input. Your task is to compute the number of cows
that are considered popular by every other cow. Input

  • Line 1: Two space-separated integers, N and M

  • Lines 2..1+M: Two space-separated numbers A and B, meaning that A thinks B is popular. Output

  • Line 1: A single integer that is the number of cows who are considered popular by every other cow.

首先用tarjan+并查集进行缩点,在得到的有向无环图上,如果有两个以上终点【就是没有出边的点】,那么输出0【因为这两个点无法互相到达】。否则那个唯一的终点就是我要找的答案。

#include<cstdio>#include<cstring>int fir[10010],next[50010],to[50010],dfn[10010],low[10010],sta[10010],fa[10010],cnt,top;bool ins[10010],end[10010];int find(int x){    if (fa[x]==x) return x;    fa[x]=find(fa[x]);    return fa[x];}int min(int x,int y){    return x<y?x:y;}void dfs(int x){    int i,j,k,y,z;    dfn[x]=low[x]=++cnt;    sta[++top]=x;    ins[x]=1;    for (i=fir[x];i;i=next[i])      if (!dfn[to[i]])      {        dfs(to[i]);        low[x]=min(low[x],low[to[i]]);      }      else      {        if (ins[to[i]])          low[x]=min(low[x],dfn[to[i]]);      }    if (dfn[x]==low[x])    {        do        {            y=sta[top--];            fa[find(y)]=x;            ins[y]=0;                   }        while (y!=x);    }}int main(){    int i,j,k,l,m,n,p,q,x,y,z,ans;    bool b,findone;    scanf("%d%d",&n,&m);    for (i=1;i<=m;i++)    {        scanf("%d%d",&x,&y);        next[i]=fir[x];        fir[x]=i;        to[i]=y;    }    for (i=1;i<=n;i++)      fa[i]=i;    for (i=1;i<=n;i++)      if (!dfn[i])        dfs(i);    memset(end,1,sizeof(end));    for (i=1;i<=n;i++)      for (j=fir[i];j;j=next[j])        if (find(to[j])!=find(i))          {            end[find(i)]=0;            break;          }    findone=0;    ans=0;    for (i=1;i<=n;i++)      if (end[find(i)])      {        if (findone==0||(findone==1&&find(i)==p))        {            ans++;            findone=1;            p=find(i);        }        else        {            printf("0\n");            return 0;        }      }    printf("%d\n",ans);}
0 0
原创粉丝点击