【洛谷】P4017最大食物鏈計數(拓撲排序)
阿新 • • 發佈:2021-02-03
【洛谷】P4017最大食物鏈計數
題目背景
你知道食物鏈嗎?Delia 生物考試的時候,數食物鏈條數的題目全都錯了,因為她總是重複數了幾條或漏掉了幾條。於是她來就來求助你,然而你也不會啊!寫一個程式來幫幫她吧。
題目描述
給你一個食物網,你要求出這個食物網中最大食物鏈的數量。
(這裡的“最大食物鏈”,指的是生物學意義上的食物鏈,即最左端是不會捕食其他生物的生產者,最右端是不會被其他生物捕食的消費者。)
Delia 非常急,所以你只有 1 秒的時間。
由於這個結果可能過大,你只需要輸出總數模上 80112002 的結果。
輸入格式
第一行,兩個正整數 n、m,表示生物種類 n 和吃與被吃的關係數 m。
接下來 m 行,每行兩個正整數,表示被吃的生物A和吃A的生物B。
輸出格式
一行一個整數,為最大食物鏈數量模上 80112002 的結果。
輸入輸出樣例
輸入
5 7
1 2
1 3
2 3
3 5
2 5
4 5
3 4
輸出
5
說明/提示
思路
拓撲排序,用一個數組儲存每一個點的食物鏈條數。
求出度為0的點的食物鏈條數和。
程式碼
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
long long ans[5010 ],sum=0,tot=0,n,m,head[5010],ins[5010];
bool outs[5010];
queue<long long> q;
struct jgt
{
long long x,y,nxt;
}f[500010];
void input()
{
long long i,j,t;
memset(ins,0,sizeof(ins));
memset(outs,true,sizeof(outs));
memset(ans,0,sizeof(ans));
scanf("%lld%lld",&n,&m);
for(i=1;i<=m;i++ )
{
tot++;
scanf("%lld%lld",&f[tot].x,&f[tot].y);
f[tot].nxt=head[f[tot].x];
head[f[tot].x]=tot;
ins[f[tot].y]++;
outs[f[tot].x]=0;
}
return;
}
void topsort()
{
long long i;
for(i=1;i<=n;i++)
if(!ins[i])
{
q.push(i);
ans[i]=1;
}
for(;!q.empty();q.pop(),sum++)
{
for(i=head[q.front()];i;i=f[i].nxt)//更新入度
{
ins[f[i].y]--;
ans[f[i].y]=(ans[f[i].y]+ans[q.front()])%80112002;//統計食物鏈條數
if(!ins[f[i].y])//當能夠到達這個點的所有點都遍歷過後將這個點加入佇列
q.push(f[i].y);
}
}
return;
}
void output()
{
long long i,answer=0;
for(i=1;i<=n;i++)//統計食物鏈條數
if(outs[i])//出度為0
answer=(answer+ans[i])%80112002;
printf("%lld",answer);
return;
}
int main()
{
input();
topsort();
output();
return 0;
}