食物链I

3795: 食物链I

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

题目描述

如图所示为某生态系统的食物网示意图,据图回答第1小题.
 
1.数一数,在这个食物网中有几条食物链(  )
现在给你n个物种和m条能量流动关系,求其中的食物链条数。
物种的名称为从1到n编号
M条能量流动关系形如
a1 b1
a2 b2
a3 b3
......
am-1 bm-1
am bm
其中 ai bi 表示能量从物种ai 流向物种bi

 

输入

第一行两个整数n 和 m。
接下来m行每行两个整数ai bi描述m条能量流动关系。
(数据保证输入数据符号生物学特点,且不会有重复的能量流动关系出现)

 

输出

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

 

样例输入

10 16
1 2
1 4
1 10
2 3
2 5
4 3
4 5
4 8
6 5
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
数据范围
1<=N<=100000  0<=m<=200000
题目保证答案不会爆int

 

来源/分类

河南OI2016 

记忆化搜索(边搜索边记录  到达过的点直接操作 不再向下搜索  以达到减少时间损耗的目的) 从食物链底端向上搜索 并记录

做这道题正好离散学了入度 出度 很亲切hhh

#include <bits/stdc++.h>

using namespace std;

const int maxn=100005;
//const int maxm=200005;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}

vector<int> v[maxn];
int in[maxn],out[maxn];
int sum[maxn]; //记录当前节点下方(食物链上方)有多少条食物链

int dfs(int cur)
{
    if(in[cur]&&!out[cur])  //到达食物链顶端
    {
        sum[cur]++;
    }
    else
    {
        for(int i=0;i<v[cur].size();i++)  //搜索当前点的各个天敌
        {
            if(sum[v[cur][i]]){    //如果搜过 直接加
                sum[cur]+=sum[v[cur][i]];
            }
            else
            {
                sum[cur]+=dfs(v[cur][i]);
            }
        }
    }
    return sum[cur];
}
int main()
{
    int n,m;
    n=read();
    m=read();
    int a,b;
    while(m--)
    {
        a=read();
        b=read();
        out[a]++; //出度+1
        in[b]++; //入度+1
        v[a].push_back(b);  //将a的天敌放入vector
    }
    int ans = 0;
    for(int i=1;i<=n;i++)
    {
        if(!in[i]&&out[i]){  //从食物链底层开始搜索  底层出度不为0 入度为0
            ans+=dfs(i);
        }
    }
    printf("%d",ans);
}

参考博客:https://blog.csdn.net/Sunshine_victory/article/details/77145695?utm_source=blogxgwz3

posted @ 2018-12-06 16:45  zangzang  阅读(539)  评论(0编辑  收藏  举报