HAOI 2016 食物链

[HAOI2016]食物链

时间限制:1 s   内存限制:128 MB

【题目描述】

如图所示为某生态系统的食物网示意图,据图回答第一小题。

1.数一数,在这个食物网中有几条食物链(   )

现在给你n个物种和m条能量流动关系,求其中的食物链条数。

物种的名称为从1n编号,m条能量流动关系形如

a1 b1

a2 b2

a3 b3

am1 bm1

am bm

其中ai bi表示能量从物种ai流向物种bi

【输入格式】

第一行两个正整数nm

接下来m行每行两个整数ai bi表示m条能量流动关系。

(数据保证输入数据符合生物学特点,且不会有重复的能量流动关系出现)

【输出格式】

一个整数即食物网中的食物链条数。

【样例输入】

10 16
1 2
1 4
1 10
2 3
2 5
4 3
4 5
4 8
6 8
7 6
7 9
8 5
9 8
10 6
10 7
10 9

【样例输出】

9

【样例解释】

就是上面题目描述1的那个图。

各个物种的编号依次为:

草<->1 兔<->2 狐<->3 鼠<->4 猫头鹰<->5 吃虫的鸟<->6 蜘蛛<->7 蛇<->8 青蛙<->9 食草昆虫<->10。

【数据范围】

1n100000,0m200000

【来源】

HAOI2016上午第一题 部分题面由ck进行调整

 

记忆化搜索,注意单个生物不能算作食物链

#include<cstdio>

#define N 100004
int sum[N];
struct node{
    int v,next;
}edge[N*2];
int rd[N],cd[N],head[N];
int n,m;
int read(){
    int x=0,f=1;char c=getchar();
    while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}
    while(c<='9'&&c>='0'){x=x*10+c-'0';c=getchar();}
    return x*f;
}
int num;int ans;
void add_edge(int x,int y){
    edge[++num].v=y;edge[num].next=head[x];head[x]=num;
}
int frist[N],cnt;

int dfs(int x)
{
    if(cd[x]==0)
    {
        sum[x]++;
    }
    for(int i=head[x];i;i=edge[i].next)
    {
        if(sum[edge[i].v])sum[x]+=sum[edge[i].v];
        else sum[x]+=dfs(edge[i].v);
    }
    return sum[x];
}
int main()
{
    //freopen("chain_2016.in","r",stdin);
    //freopen("chain_2016.out","w",stdout);
    n=read();m=read();
    int a,b;
    for(int i=1;i<=m;i++)
    {
        a=read();b=read();
        add_edge(a,b);
        cd[a]++;
        rd[b]++;
    }
    for(int i=1;i<=n;i++)
    {
        if(rd[i]==0&&cd[i]!=0)
        {
            ans+=dfs(i);
        }
    }
    printf("%d",ans);
    return 0;
}

 

posted @ 2017-06-20 20:26  zzzzx  阅读(326)  评论(0编辑  收藏  举报