洛谷 P4017 最大食物鏈計數

2022-03-20 04:34:25 字數 1692 閱讀 6520

洛谷傳送門

你知道食物鏈嗎?delia生物考試的時候,數食物鏈條數的題目全都錯了,因為她總是重複數了幾條或漏掉了幾條。於是她來就來求助你,然而你也不會啊!寫乙個程式來幫幫她吧。

給你乙個食物網,你要求出這個食物網中最大食物鏈的數量。

(這裡的「最大食物鏈」,指的是生物學意義上的食物鏈,即最左端是不會捕食其他生物的生產者,最右端是不會被其他生物捕食的消費者。)

delia非常急,所以你只有1秒的時間。

由於這個結果可能過大,你只需要輸出總數模上80112002的結果。

第一行,兩個正整數n、m,表示生物種類n和吃與被吃的關係數m。

接下來m行,每行兩個正整數,表示被吃的生物a和吃a的生物b。

一行乙個整數,為最大食物鏈數量模上80112002的結果。

輸入 #1複製

輸出 #1複製

各測試點滿足以下約定:

【補充說明】

資料中不會出現環,滿足生物學的要求。(感謝@akee )

一道拓撲排序的好題。

前置知識是拓撲排序。如有不會的小夥伴請移步:

拓撲排序詳解

我個人認為拓撲排序本身並沒有特別難以理解,但是應用在題目上卻並不是那麼容易。

首先我們發現這道題是一道圖論題。(這個要是看不出來可真的gg了)

對於圖論題,我們要好好分析題目大意,據此判斷模板和演算法。那麼這道題為什麼要用拓撲排序呢

首先,我們要找最大食物鏈,最大食物鏈是什麼呢?根據題目的描述,是最猛的那種生物不能被任何生物吃掉,最弱的生物不能吃任何生物。模擬到圖上,就是從乙個入度為0的點,到乙個出度為0的點。我們只需要找出所有這種數量即可。

用遞推即可解決計數的問題:

#include#includeusing namespace std;

const int maxn=5010;

const int maxm=5*1e5+10;

const int mod=80112002;

char *p1,*p2,buf[100000];

#define nc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?eof:*p1++)

int read()

while(ch>47) x=(((x<<2)+x)<<1)+ch-48,ch=nc();

return x*f;

}int n,m;

int tot,head[maxn],nxt[maxm],to[maxm];

int chudu[maxn],rudu[maxn];

int f[maxn],ans;

queueq;

void add(int x,int y)

int main()

for(int i=1;i<=n;i++)

if(rudu[i]==0)

f[i]=1,q.push(i);

while(!q.empty())}}

printf("%d",ans);

return 0;

}

P4017 最大食物鏈計數(洛谷)

傳送門 這道題就是記憶化搜尋。中文題面,不解釋 這道題拓撲排序,存在 不存在拓撲路徑都得算入。用鄰接表實現 根據題目的最大食物鏈的規定,我們需要從出度為零的點開始搜,一直搜到入度為零的點結束。也可以從入度為0的點開始,到出度為0的點結束 這樣算一條路徑。然後累加即可。用vis標記一下。即我們從出度為...

洛谷 P4017 最大食物鏈計數

看到這種明顯的有向無環圖,並且等級分明,自然而然就能想到拓補排序啦。對於這道題,我們就可以利用最短路計數的那種思想 不知道也沒關係 設 j 是 i 的後繼,dis i 表示以 i 為結尾有多少條食物鏈,那麼就可以得到 dis j dis i 然後往後面推,直到拓補排序結束。因為題目要求的是沒有可以吃...

P4017 最大食物鏈計數

你知道食物鏈嗎?delia生物考試的時候,數食物鏈條數的題目全都錯了,因為她總是重複數了幾條或漏掉了幾條。於是她來就來求助你,然而你也不會啊!寫乙個程式來幫幫她吧。給你乙個食物網,你要求出這個食物網中最大食物鏈的數量。這裡的 最大食物鏈 指的是生物學意義上的食物鏈,即最左端是不會捕食其他生物的生產者...