P4017 最大食物链计数

P4017

A被B吃,则由A向B连一条有向边,最终得到一个有向图。起点为入度为0的点,终点为出度为0的点,相当于算从起点到终点有多少条不同的路径。

我们设dp[i]表示从起点到i点的路径条数,最终的答案就是所有出度为0的点的dp值相加。dp过程用拓扑排序处理即可。

 1 #include <bits/stdc++.h>
 2 #define ll long long
 3 #define mod 80112002
 4 using namespace std;
 5 const int N = 5010, M = 500010;
 6 int n, m, chu[N], ru[N], dp[N];
 7 vector<int> e[N];
 8 void Topo() {//拓扑排序 
 9     queue<int> q;
10     for (int i = 1; i <= n; i ++)
11         if (!ru[i]) q.push(i), dp[i] = 1;
12     while (!q.empty()) {
13         int x = q.front(); q.pop();
14         for (int i = 0; i < e[x].size(); i ++) {
15             int y = e[x][i];
16             ru[y] --;
17             dp[y] = (dp[y] + dp[x]) % mod;
18             if (!ru[y]) q.push(y);
19         }
20     }
21 }
22 int main() {
23     scanf("%d %d", &n, &m);
24     for (int i = 1; i <= m; i ++) {
25         int x, y; scanf("%d %d", &x, &y);
26         e[x].push_back(y), chu[x] ++, ru[y] ++;
27     }
28     Topo();
29     ll ans = 0;
30     for (int i = 1; i <= n; i ++) 
31         if (!chu[i]) ans = (ans + dp[i]) % mod;
32     printf("%lld\n", ans);
33     return 0;
34 }
posted @ 2022-10-10 14:37  YHXo  阅读(50)  评论(0)    收藏  举报