[HAOI2016]食物鏈

[HAOI2016]食物鏈node

題目描述ios

 

如圖所示爲某生態系統的食物網示意圖,據圖回答第1小題如今給你n個物種和m條能量流動關係,求其中的食物鏈條數。物種的名稱爲從1到n編號M條能量流動關係形如a1 b1a2 b2a3 b3......am-1 bm-1am bm其中ai bi表示能量從物種ai流向物種bi,注意單獨的一種孤立生物不算一條食物鏈ide

輸入輸出格式spa

輸入格式:

3d

第一行兩個整數n和m,接下來m行每行兩個整數ai bi描述m條能量流動關係。(數據保證輸入數據符號生物學特色,且不會有重複的能量流動關係出現)1<=N<=100000 0<=m<=200000題目保證答案不會爆 intcode

輸出格式:blog

一個整數即食物網中的食物鏈條數排序

輸入樣例#1 string

10 16it

1 2

1 4

1 10

2 3

2 5

4 3

4 5

4 8

6 5

7 6

7 9

8 5

9 8

10 6

10 7

10 9

輸出樣例#1 

9

講解:

這道題十分的水,是一道拓撲排序的模板題,只需注意單獨的一種孤立生物不算一條食物鏈,以後就是一個dp。

代碼實現:

#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<queue>
using namespace std;
const int N=100010,M=200010;
struct node
{
    int to,next;
}edge[M];
int head[N],cnt=-1,n,m;
void add(int x,int y)
{
    edge[++cnt].to=y;
    edge[cnt].next=head[x];
    head[x]=cnt;
}                                     //建邊 
int ind[N],dp[N],book[N],ans;
int main()
{
    memset(head,-1,sizeof(head));
    int i,j,x,y;
    scanf("%d%d",&n,&m);
    for(i=1;i<=m;i++)
    {
        scanf("%d%d",&x,&y);
        add(x,y);                     //有向邊 
        ind[y]++;                     //每個入度 
    }
    queue<int> q;
    for(i=1;i<=n;i++)
    {
        if(ind[i]==0)
        {
            q.push(i);
            dp[i]=1;
            book[i]=1;
        }
    }                                //尋找拓撲圖(DAG)的起點 
    while(!q.empty())
    {
        int x=q.front(),i,flag=0;
        q.pop();
        for(i=head[x];i!=-1;i=edge[i].next)
        {
            flag=1;
            ind[edge[i].to]--;
            dp[edge[i].to]+=dp[x];
            if(ind[edge[i].to]==0) q.push(edge[i].to);
        }                           //遍利當前節點的全部出邊,並進行dp(累加) 
        if(flag==0 && book[x]==0) ans+=dp[x]; 
                                    //只有當前節點沒有出邊(就是圖的終點)
                                    //而且也不是孤立的生物時纔是答案 
    }
    cout<<ans<<endl;
    return 0;
}
View Code
相關文章
相關標籤/搜索