zl程序教程

您现在的位置是:首页 >  其它

当前栏目

食物链计数

计数
2023-09-27 14:26:25 时间

题目描述
​ 给你一个食物网,你要求出这个食物网中所有食物链的数量。(这里的“食物链”,指的是生物学意义上的食物链,即最左端是不会捕食其他生物的生产者,最右端是不会被其他生物捕食的消费者。)

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

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

​ 接下来 m 行,每行两个正整数 A,B。表示生物 B 吃生物 A。保证不会出现环。

输出
​ 一行一个整数,为最大食物链数量模上 108+7 的结果。

样例输入
7 9
1 3
1 4
2 3
2 4
2 5
3 6
4 6
4 7
5 7
样例输出
7
数据规模与约定
​ 时间限制:1 s

​ 内存限制:256 M

​ 100% 的数据保证 1≤n≤5000,1≤m≤500000

#include <iostream>
#include <cstring>
#include <queue>
using namespace std;

struct edge {
	int to, next;
};

int n, m,head[5005],in_degree[5005],out_degree[5005],ans[5005];
queue<int> que;
edge edg[500005];

int main() {
	memset(head, -1, sizeof(head));
	cin >> n >> m;
	for (int i = 0; i < m; i++) {
		int a, b;
		cin >> a >> b;
		edg[i].to = b;
		edg[i].next = head[a];
		head[a] = i;
		in_degree[b]++;
		out_degree[a]++;
	}
	for (int i = 1; i <= n; i++) {
		if (in_degree[i] == 0) {
			que.push(i);
			ans[i] = 1;
		}
	}
	while (!que.empty()) {
		int t = que.front();
		que.pop();
		for (int i = head[t]; i != -1; i = edg[i].next) {
			int e = edg[i].to;
			ans[e] += ans[t];
			ans[e] %= 100000007;
			in_degree[e]--;
			if (in_degree[e] == 0) {
				que.push(e);
			}
		}
	}
	int fin = 0;
	for (int i = 1; i <= n; i++) {
		if (out_degree[i] == 0) {
			fin += ans[i];
			fin %= 100000007;
		}
	}
	cout << fin << endl;
	return 0;
}