洛谷 P4017 【最大食物链计数】

看到这种明显的有向无环图,并且等级分明,自然而然就能想到拓补排序啦。对于这道题,我们就可以利用最短路计数的那种思想(不知道也没关系),设\(j\)\(i\)的后继,\(dis_i\)表示以\(i\)为结尾有多少条食物链,那么就可以得到\(dis_j+=dis_i\),然后往后面推,直到拓补排序结束。因为题目要求的是没有可以吃其他动物的动物为食物链最后,所以统计出度为0的点的\(dis\)值即可。

代码:

#include <bits/stdc++.h>
using namespace std;
int n , m , ans;
int f1[5010] , f2[5010] , dis[5010];
vector<int> e[5010];
int main(){
	cin >> n >> m;
	for(int i = 1; i <= m; i++){
		int x , y;
		cin >> x >> y;
		e[x].push_back(y);
		f1[y]++ , f2[x]++;	//一个入度,一个出度 
	}
	queue<int> q;
	for(int i = 1; i <= n; i++)
		if(!f1[i]) q.push(i) , dis[i] = 1;	//初始化一下 ,准备拓补排序 
	while(!q.empty()){
		int x = q.front();
		q.pop();
		for(int i = 0; i < e[x].size(); i++){
			dis[e[x][i]] += dis[x];
			dis[e[x][i]] %= 80112002;	//记得%啊,当时没 % 只有20分qnq 
			f1[e[x][i]]--;
			if(!f1[e[x][i]]) q.push(e[x][i]);
		}
	}
	for(int i = 1; i <= n; i++)
		if(!f2[i]) ans += dis[i] , ans %= 80112002;	//统计答案~ 
	cout << ans;
	return 0;
}
posted @ 2020-06-30 19:57  那一条变阻器  阅读(96)  评论(0编辑  收藏  举报