You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
|
|
#include <bits/stdc++.h>
|
|
|
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
const int MOD = 80112002;
|
|
|
|
|
const int N = 500010;
|
|
|
|
|
int n; //生物种类
|
|
|
|
|
int m; //吃与被吃的关系数
|
|
|
|
|
vector<int> edge[N]; //保存DAG图的邻接表
|
|
|
|
|
int ind[N]; //每个生物种类的入度
|
|
|
|
|
int ans; //为最大食物链数量模上 80112002 的结果
|
|
|
|
|
int f[N]; //记忆化搜索的记录数组
|
|
|
|
|
//下面的代码得分通过记忆化搜索AC掉本题
|
|
|
|
|
/**
|
|
|
|
|
* 功能:计算以x出发点的所有食物链条数
|
|
|
|
|
* @param x
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
int dfs(int x) {
|
|
|
|
|
if (f[x]) return f[x];
|
|
|
|
|
//如果当前节点没有出度,说明到了食物链顶端,就是一条完整的食物链,也就是递归的终点,需要+1了~
|
|
|
|
|
if (!edge[x].size()) return 1;
|
|
|
|
|
|
|
|
|
|
//遍历所有的邻接边,所有分支食物链接数量和就是当前结点的食物链数量
|
|
|
|
|
int sum = 0;
|
|
|
|
|
for (int i = 0; i < edge[x].size(); i++) sum = (sum + dfs(edge[x][i])) % MOD;
|
|
|
|
|
return f[x] = sum % MOD; //走一步模一步
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int main() {
|
|
|
|
|
cin >> n >> m;
|
|
|
|
|
//m种关系
|
|
|
|
|
for (int i = 1; i <= m; i++) {
|
|
|
|
|
int x, y;
|
|
|
|
|
cin >> x >> y; //被吃的生物x和吃x的生物y
|
|
|
|
|
edge[x].push_back(y); //用邻接表记录下食物链的关系,x被y吃掉,由x向y引一条有向边
|
|
|
|
|
ind[y]++; //y入度++
|
|
|
|
|
}
|
|
|
|
|
//对于每个生物,如果入度为0,表示是最底层的生物,开始进行深搜,所有的“食物链条数”
|
|
|
|
|
for (int i = 1; i <= n; i++) if (!ind[i]) ans = (ans + dfs(i)) % MOD;
|
|
|
|
|
cout << ans << endl;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|