食物链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
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条能量流动关系。
(数据保证输入数据符号生物学特点,且不会有重复的能量流动关系出现)
接下来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
来源/分类
记忆化搜索(边搜索边记录 到达过的点直接操作 不再向下搜索 以达到减少时间损耗的目的) 从食物链底端向上搜索 并记录
做这道题正好离散学了入度 出度 很亲切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