1. 程式人生 > 其它 >【洛谷】P4017最大食物鏈計數(拓撲排序)

【洛谷】P4017最大食物鏈計數(拓撲排序)

技術標籤:圖論拓撲排序

【洛谷】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; }