洛谷P4017 最大食物链计数

害 这个题 我做了好久都不会 最后看了一位大佬的题解,会了他的一种方法,但是第二种 方法我出现了RE,害 先记录一下 通过的那个方法。

对于这个题,与其说他是属于搜索,我硬是一点搜索的味道也没找到。反而,有一点动态规划的感觉(害 还是因为我太菜了 好伤感 我好想变强呀 呜呜呜呜呜)

转回正题:对于这个题,要找到最长的食物链,那么一定是从入度为零的生产者开始,然后到出度为零的消费者(最厉害的消费者结束),我们每次将入度为一的生产者入队列,并且记录他的路数(最开始的入度为零的生产者路数为1),通过吃与被吃的关系将他的路数加到吃它的消费者上,然后,将其出队列。如果找到一个节点的入度和出度均为零,则找到了一条最长的食物链数。

对于,我这个小菜鸟而言 比较难的是记录构图的过程。对于这个图,他有方向,所以我们需要开两个数组记录每个节点的入度与出度这样就记录下来边的方向关系,对了,还有我觉得那个大佬的代码很精彩的地方是他利用一个数组记录了,一个生物被几个生物吃。

接下来,就说一下代码,

首先有 ru[5005],chu[5005],记录入度与出度。然后有 f[5005]用于记录到达每个节点可以走的路数,然后h[5005]用于记录一个生物被几个生物所吃。

完整的代码如下:

#include<iostream>
#include<queue>
using namespace std;
#define  N  80112002 
queue<int> dui;
int n,m,sum;
int chu[5005],ru[5005],h[5005],f[5005];
struct point{
    int a,b,n;
}re[500005];
int main(){
    int a,b;
    cin>>n>>m;
    for(int i = 1;i <= m;i++){
        cin>>a>>b;
        re[i].a = a;
        re[i].b = b;
        re[i].n = h[a];
        h[a] = i;
        chu[a]++;
        ru[b]++;
    }
    for(int j = 1;j <= n;j++){
        if(ru[j] == 0){
            dui.push(j);
            f[j] = 1;
        }
    }
    while(!dui.empty()){
        int a = dui.front();
        dui.pop();
        for(int k = h[a];k;k = re[k].n){    //如果k不为零,证明还存在吃这个生物的消费者
            int b = re[k].b;
            ru[b]--;
            f[b] += f[a];
            f[b] %= N;
            if(ru[b] == 0){
                if(chu[b] == 0){
                    cout<<f[b]<<endl;
                //    sum %= N;
                }
                else
                    dui.push(b);
            }
        }
    }
//    cout<<sum<<endl;
    return 0;
}

okok  下一题  加油小灰灰!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

posted @ 2023-01-05 15:41  啥都不会的灰太狼  阅读(85)  评论(0编辑  收藏  举报