[HAOI2016]食物链
时间限制:1 s 内存限制:128 MB
【题目描述】
如图所示为某生态系统的食物网示意图,据图回答第一小题。
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 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。
【数据范围】
1≤n≤100000,0≤m≤200000。
【来源】
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; }