《洛谷深入浅出基础篇》P4017最大食物链————拓扑排序

news/2024/7/15 17:06:22 标签: 算法, 图论, c++, 数据结构

上链接:P4017 最大食物链计数 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)icon-default.png?t=N7T8https://www.luogu.com.cn/problem/P4017

上题干:

 

题目背景

你知道食物链吗?Delia 生物考试的时候,数食物链条数的题目全都错了,因为她总是重复数了几条或漏掉了几条。于是她来就来求助你,然而你也不会啊!写一个程序来帮帮她吧。

题目描述

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

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

Delia 非常急,所以你只有 11 秒的时间。

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

输入格式

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

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

输出格式

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

输入输出样例

输入 #1复制

5 7
1 2
1 3
2 3
3 5
2 5
4 5
3 4

输出 #1复制

5

说明/提示

各测试点满足以下约定:

【补充说明】

数据中不会出现环,满足生物学的要求。

数据大小:M=5e5+7,N=5e3+7

 取模:mod=80112002

一个vector 用来储存点的关系,

一个数组f来储存答案。

一个数组outd表示入度,

一个数组ind表示出度。

一个队列q每次用来增加新的入度为0的点,和删除已经用过的入度为0的点。

开始分析:

我们要求所有的完整食物链的个数,也就是求所有起点是生产者,终点是最高级的消费者。

我们可以得到这样的图:

假设数组f【i】表示以生产者为起点,到i号生物的路径数量。

由此我们可以得到递推关系。

f【5】= f【2】+f【3】+f【4】

f【2】=f【1】

f【3】=f【2】+f【1】

f【4】=f【3】

f【1】=1;

这就是这样例的结果。f【5】=1+2+2=5

先将所有入度为0的数字的f【】初始化为1,其他的初始化为0;

1对其他能吃它的贡献为f【1】,现在我们将1删除,然后将1的捕食关系删除,也就是能吃1的入度-1,然后给它们加上f【1】,也就是f【2】=f【1】,f【3】=f【1】

现在场上剩下的图像就是:

继续找入度为0的点,现在是2,那么删去2,给能吃2的加上2的贡献,

f【3】=f【1】+f【2】

f【5】=f【2】

然后删除后的图像就是这样:

继续找图中入度为0的点:3

删除3的痕迹,给能吃3的加上3的贡献

f【5】=f【2】+f【3】

f【4】=f【3】

最后删除4,以及4 的痕迹,给能吃4的加上4的贡献

f【5】=f【2】+f【3】+f【4】=5

此时剩下的一定是最高消费者,那么其代表的数值就一定是答案。

上代码:


const int mod = 80112002;
const int M = 5e5+7;
const int N = 5e3 + 7;
queue<int > q;
int outd[N];
int ind[N];
int f[N];
int ans;
vector<int > p[N];
int main()
{
	int n, m;
	cin >> n >> m;
	for (int i = 0; i < m; i++)
	{
		int a, b;
		cin >> a >> b;
		p[b].push_back(a);
		outd[b]++;
		ind[a]++;
	}
	for (int i = 1; i <= n; i++)
	{
		if (ind[i] == 0) {
			q.push(i);
			f[i] = 1;
		}
	}
	while (!q.empty()) {
		int x = q.front();
		q.pop();
		for (int i = 0; i < p[x].size(); i++)
		{
			f[p[x][i]] += f[x];
			f[p[x][i]] %= mod;
			ind[p[x][i]]--;
			if (ind[p[x][i]] == 0)q.push(p[x][i]);
		}
	}
	for (int i = 1; i <= n; i++)
	{
		if (outd[i] == 0)ans = (ans+f[i])%mod;
	}
	cout << ans;
}


http://www.niftyadmin.cn/n/5209278.html

相关文章

极智AI | LLM大模型部署框架之OpenLLM

欢迎关注我的公众号 [极智视界],获取我的更多经验分享 大家好,我是极智视界,本文来介绍一下 LLM大模型部署框架之OpenLLM。 邀您加入我的知识星球「极智视界」,星球内有超多好玩的项目实战源码下载,链接:https://t.zsxq.com/0aiNxERDq 由于 LLM 大模型在模型结构、模型规…

VUE3+Springboot实现SM2完整步骤

一.VUE3代码实现 1.安装依赖 npm install --save sm-crypto 2.导入sm2 const sm2 require(sm-crypto).sm2 3.定义公钥私钥 var privateKey "私钥";//解密使用 var publicKey "公钥";//加密使用 4.设置加密模式 //cipherMode [加密模式 C1C3C2:1,…

微信小程序完整实现微信支付功能(SpringBoot和小程序)

1.前言 不久前给公司实现支付功能&#xff0c;折腾了一阵子&#xff0c;终于实现了&#xff0c;微信支付对于小白来说真的很困难&#xff0c;特别是没有接触过企业级别开发的大学生更不用说&#xff0c;因此尝试写一篇我如何从小白实现微信小程序支付功能的吧&#xff0c;使用…

Shell脚本:Linux Shell脚本学习指南(第二部分Shell编程)二

第二部分&#xff1a;Shell编程&#xff08;二&#xff09; 十一、Shell数组&#xff1a;Shell数组定义以及获取数组元素 和其他编程语言一样&#xff0c;Shell 也支持数组。数组&#xff08;Array&#xff09;是若干数据的集合&#xff0c;其中的每一份数据都称为元素&#…

uniapp 轮播图(含组件封装,自动注册全局组件)

效果预览 组件封装 src\components\SUI_Swiper.vue 可参考官网配置更多属性 swipernavigator <script setup lang"ts"> import { ref } from vue defineProps({config: Object, })const activeIndex ref(0) const change: UniHelper.SwiperOnChange (e) &…

Spring Validation实践及其实现原理

Bean Validation 2.0 注解 校验空值 Null&#xff1a;验证对象是否为 null NotNull&#xff1a;验证对象是否不为 null NotEmpty&#xff1a;验证对象不为 null&#xff0c;且长度&#xff08;数组、集合、字符串等&#xff09;大于 0 NotBlank&#xff1a;验证字符串不为 nul…

pydantic.errors.PydanticUserError: If you use `@root_validator`....

使用langchain时&#xff0c;import langchain时报错内容如下&#xff1a; pydantic.errors.PydanticUserError: If you use root_validator with preFalse (the default) you MUST specify skip_on_failureTrue. Note that root_validator is deprecated and should be repla…

Day38:518.零钱兑换II、377. 组合总和 Ⅳ

文章目录 518.零钱兑换II思路代码实现 377. 组合总和 Ⅳ思路代码实现 518.零钱兑换II 题目链接 思路 确定dp数组&#xff08;dp table&#xff09;以及下标的含义 dp[j]&#xff1a;组合元素和为j的组合方式确定递推公式 题目不是选取最优解&#xff0c;而是求路径总和&…