解题思路:食物链,单项捕食关系,可以抽象成一个有向图,然后题目还给出了一个条件,每一条食物链最左端入度为0,最右端出度为0,而且又没有环,题目给出的条件很多,很容易就判断出这道题目用拓扑排序做,每次删节点的时候,把删去节点的去向节点的食物链数加1,因为食物链的终端出度为零,在拓扑排序的基础上我们需要加入一个数组记录每个节点的出度,最后枚举出度为0的节点,最后把出度为0的食物链条数累加起来就是答案。
下面附上ac代码
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <string>
#include <cstring>
#include <queue>
#include <set>
#include <map>
#include <vector>
#define dbg(a) cout<<#a<<" : "<<a<<endl;
#define IOS ios_base::sync_with_stdio(false); cin.tie(NULL);
#define PAUSE system("pause")
#define sd(a) scanf("%d",&a)
#define sll(a) scanf("%lld",&a)
#define sdd(a,b) scanf("%d%d",&a,&b)
#define sddd(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define sf(a) scanf("%lf",&a)
#define sff(a,b) scanf("%lf%lf",&a,&b)
#define sfff(a,b,c) scanf("%lf%lf%lf",&a,&b,&c)
using namespace std;
typedef long long ll;
const int maxn=500005;
const int mod=80112002;
vector<int> ve[maxn];
queue<int> q;
int ind[maxn];
int oud[maxn];
int num[maxn];
int main()
{
int n,m;
sdd(n,m);
int u,v;
for(int i=0;i<m;i++)
{
sdd(u,v);
ve[u].push_back(v);
oud[u]++;
ind[v]++;
}
for(int i=1;i<=m;i++)
if(!ind[i]){
q.push(i);
num[i]=1;
}
while(!q.empty())
{
int cur=q.front();
for(int i=0;i<ve[cur].size();i++)
{
int tmp=ve[cur][i];
ind[tmp]--;
if(!ind[tmp]) q.push(tmp);
num[tmp]=(num[tmp]+num[cur])%mod;
}
q.pop();
}
int maxx=0;
for(int i=1;i<=n;i++)
{
if(!oud[i]) maxx=(maxx+num[i])%mod;
}
printf("%d\n",maxx);
//PAUSE;
return 0;
}