200字范文,内容丰富有趣,生活中的好帮手!
200字范文 > 拓扑排序(最大食物链计数 图文结合)

拓扑排序(最大食物链计数 图文结合)

时间:2020-07-04 04:54:59

相关推荐

拓扑排序(最大食物链计数 图文结合)

拓扑排序

拓扑排序(topological-sort)是指由某个集合上的一个偏序得到该集合上的一个全序的操作。拓扑排序常用来确定一个依赖关系集中,事物发生的顺序

拓扑排序是对有向无环图的顶点的一种排序,它使得如果存在一条从顶点A到顶点B的路径,那么在排序中B出现在A的后面。

最大食物链计数

给你一个食物网,你要求出这个食物网中最大食物链的数量。

(这里的“最大食物链”,指的是生物学意义上的食物链,即最左端是不会捕食其他生物的生产者,最右端是不会被其他生物捕食的消费者。)

由于这个结果可能过大,你只需要输出总数模上 80112002的结果。

输入格式

第一行,两个正整数 n、m,表示生物种类 n 和吃与被吃的关系数 m。

接下来 m 行,每行两个正整数,表示被吃的生物A和吃A的生物B。

输出格式

一行一个整数,为最大食物链数量模上 80112002的结果。

输入输出样例

输入

5 7

1 2

1 3

2 3

3 5

2 5

4 5

3 4

输出

5

说明/提示

各测试点满足以下约定:

洛谷题目链接

解题思路

①、对于图论类型有向无环图的题,可以采用拓扑排序。

②、对每个节点的路径进行逐个递推,最终每个有向无环的终点之和便是答案。

ps:在拓扑排序里,每个点只会入队一次,每条边只会通过一次,时间复杂度为O(N+M)。

洛谷题解

#include<bits/stdc++.h>#define ll long longusing namespace std;ll total[5010], ans=0;int start[5010], end[5010];vector <int> g[5010];//采用邻接表int main(){int n, m, a, b;cin.tie(0);ios::sync_with_stdio(false); memset(total, 0, sizeof(total));memset(start, 0, sizeof(start));memset(end, 0, sizeof(end));cin>>n>>m;for(int i=1; i<=m; i++){cin>>a>>b;start[a]++;//记录 a 有多少条出路 end[b]++;//记录有多少条路径能到达 b g[a].push_back(b);//a 可到达 b}//插入全部起点 queue <int> q;for(int i=1; i<=n; i++){if(end[i]==0){//没有路径能到达 i,i为起点total[i]=1;q.push(i);}}while(!q.empty()){int tmp=q.front();q.pop();//扫描tmp能到达的节点for(int i=0; i<g[tmp].size(); i++){int k=g[tmp][i];total[k] = (total[k]+total[tmp])%80112002;end[k]--;//少一条能到达 k 的路径 if(end[k]==0){//没有路径能到达 k if(start[k]==0){// k 没有出路 ans = (ans + total[k])%80112002;}else{q.push(k);}}}}cout<<ans; return 0;}

一直将自己的学习经验分享给有需要的人。

我是小郑,一个坚持不懈的小白

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。