1. 程式人生 > 其它 >第38天--演算法(最大食物鏈計數---筆試遇到無數次的演算法題---Java題解)

第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;
    }
}