题目描述
如图所示为某生态系统的食物网示意图,据图回答第1小题现在给你n个物种和m条能量流动关系,求其中的食物链条数。物种的名称为从1到n编号M条能量流动关系形如a1 b1a2 b2a3 b3......am-1 bm-1am bm其中ai bi表示能量从物种ai流向物种bi,注意单独的一种孤立生物不算一条食物链
输入输出格式
输入格式:第一行两个整数n和m,接下来m行每行两个整数ai bi描述m条能量流动关系。(数据保证输入数据符号生物学特点,且不会有重复的能量流动关系出现)1<=N<=100000 0<=m<=200000题目保证答案不会爆 int
输出格式:一个整数即食物网中的食物链条数
输入输出样例
输入样例#1:
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
输出样例#1:
9
入度为零的是生产者,作为开头,出度为零的是终极消费者,作为结尾,求从入度为零的走到出度为零的路径总数。
1 #include<cstdio> 2 #include<cstring> 3 4 const int MAXN = 100100; 5 struct Edge{ 6 int to,nxt; 7 }e[MAXN<<1]; 8 int head[MAXN]; 9 int f[MAXN]; 10 int ru[MAXN],ch[MAXN]; 11 int n,m,ans,cnt; 12 13 void add(int u,int v) 14 { 15 ++cnt; 16 e[cnt].to = v; 17 e[cnt].nxt = head[u]; 18 head[u] = cnt; 19 } 20 int search(int a) 21 { 22 if (f[a]) return f[a]; //记忆化搜索 23 if (ch[a]==0) return 1; //走到尽头(出度为零的点),返回1 24 int sum = 0; 25 for (int i=head[a]; i; i=e[i].nxt) //找所有连着的边 26 { 27 sum += search(e[i].to); 28 } 29 f[a] = sum; //记忆化搜索 30 return sum; 31 } 32 int main() 33 { 34 scanf("%d%d",&n,&m); 35 for (int u,v,w,i=1; i<=m; ++i) 36 { 37 scanf("%d%d",&u,&v); 38 add(u,v); 39 ru[v]++; 40 ch[u]++; 41 } 42 for (int i=1; i<=n; ++i) //找入度为零的点(出度也要有) 43 if (ru[i]==0 && ch[i]!=0) ans += search(i); 44 printf("%d",ans); 45 return 0; 46 }