P4017 最大食物链计数
拓扑排序,有向图
记录每个点的入度,进行拓扑排序
然后怎么计算ans?
通过每个点的入度传递到子节点,在食物链的末尾加上即可,注意求余。
原理:
代码:
#include<iostream>
#include<vector>
#include<algorithm>
#include<math.h>
#include<sstream>
#include<string>
#include<string.h>
#include<iomanip>
#include<stdlib.h>
#include<map>
#include<queue>
#include<limits.h>
#include<climits>
#include<fstream>
#include<stack>
typedef long long ll;
using namespace std;
const int M = 80112002;
const int N = 1e4;
ll rd[N], rd_sist[N];
vector<ll>G[N];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
ll nget = 0;
ll n, m;
cin >> n >> m;
for (int i = 0; i < m; i++)
{
ll u, v; cin >> v >> u;
G[u].push_back(v);
rd[v]++;
}
queue<ll>qid;
for (int i = 1; i <= n; i++)if (!rd[i]) { qid.push(i); nget++; rd_sist[i] = 1; }
ll ans = 0;
while (!qid.empty())
{
int now = qid.front(); qid.pop();
if (!G[now].size()) { ans += rd_sist[now]; ans %= M; }
for (int i = 0; i < G[now].size(); i++)
{
ll v = G[now][i];
rd[v]--;
rd_sist[v] += rd_sist[now];
rd_sist[v] %= M;
if (!rd[v])
{
nget++;
qid.push(v);
}
}
}
cout << ans;
return 0;
}