第38天--算法(最大食物链计数---笔试遇到无数次的算法题---Java题解)

题目描述

给你一个食物网,你要求出这个食物网中最大食物链的数量。

(这里的“最大食物链”,指的是生物学意义上的食物链,即最左端是不会捕食其他生物的生产者,最右端是不会被其他生物捕食的消费者。)

Delia 非常急,所以你只有 1 秒的时间。

由于这个结果可能过大,你只需要输出总数模上 80112002 的结果。

输入格式

第一行,两个正整数 n、m,表示生物种类 n 和吃与被吃的关系数 m

接下来 m 行,每行两个正整数,表示被吃的生物A和吃A的生物B。

输出格式

一行一个整数,为最大食物链数量模上 80112002 的结果。

 

我的题解:深度优先遍历+记忆化搜索(不用记忆化搜索有部分测试用例会超时)

 

import java.util.*;
public class Main {
    static int mod = 80112002;
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int x = sc.nextInt();
        int y = sc.nextInt();
        int pre[][] = new int[y][2];
        for(int i = 0;i < y;i ++) {
            pre[i][0] = sc.nextInt();
            pre[i][1] = sc.nextInt();
        }
        int sb[] = new int[x + 1];
        int nb[] = new int[x + 1];
        int ans = 0;
        int map[] = new int[x + 1];
        for(int i = 0;i < x + 1;i ++) {
            map[i] = -999;
        }
        int lian[][] = new int[x + 1][x + 1];
        // sb[xxx] == 0 -> 最垃圾的被吃的
        // nb[xxx] == 0 -> 最牛逼的吃东西的
        for(int i = 0;i < y;i ++) {
            sb[pre[i][1]] ++;
            nb[pre[i][0]] ++;
            lian[pre[i][0]][pre[i][1]] = 1;
        }
        for(int i = 1;i <= x;i ++) {
            if(nb[i] == 0) {
                ans = (ans + dfs(lian,sb,nb,i,x,map)) % mod;
            }
        }
        System.out.println(ans);
    }
    public static int dfs(int lian[][],int sb[],int nb[],int i,int x,int map[]) {
        if(map[i] != -999) {
            return map[i];
        }
        if(sb[i] == 0) {
            return 1;
        }
        int ans = 0;
        for(int j = 1;j <= x;j ++) {
            if(lian[j][i] == 1) {
                ans = (ans + dfs(lian,sb,nb,j,x,map)) % mod;
            }
        }
        map[i] = ans;
        return ans;
    }
}

 

posted @ 2022-03-09 10:41  现在开始努力  阅读(119)  评论(0)    收藏  举报