二叉苹果树

    xiaoxiao2023-12-01  162

    题目描述

    有一棵苹果树,如果树枝有分叉,一定是分 2 叉(就是说没有只有 1 个儿子的结点)。 这棵树共有 N 个结点(叶子点或者树枝分叉点),编号为 1-N,树根编号一定是 1。 我们用一根树枝两端连接的结点的编号来描述一根树枝的位置。下面是一颗有 4 个树枝 的树: 2 5 \ / 3 4 \ / 1 现在这颗树枝条太多了,需要剪枝。但是一些树枝上长有苹果。 给定需要保留的树枝数量,求出最多能留住多少苹果。

    输入格式:

    第 1 行 2 个数,N 和 Q(1<=Q<= N,1<N<=100)。 N 表示树的结点数,Q 表示要保留的树枝数量。接下来 N-1 行描述树枝的信息。 每行 3 个整数,前两个是它连接的结点的编号。第 3 个数是这根树枝上苹果的数量。 每根树枝上的苹果不超过 30000 个。

    输出格式:

    一个数,最多能留住的苹果的数量。

    输入样例:

    5 2 1 3 1 1 4 10 2 3 20 3 5 20

    输入样例:

    21

    代码实现
    import java.util.ArrayList; import java.util.Scanner; public class Main { public Main() { Scanner sc=new Scanner(System.in); int N,Q; N=sc.nextInt(); Q=sc.nextInt(); int[][] Mat=new int[N+1][N+1]; for(int i=1;i<=N;i++) for(int j=1;j<=N;j++) Mat[i][j]=-1; for(int i=0;i<N-1;i++) { int x,y,weight; x=sc.nextInt(); y=sc.nextInt(); weight=sc.nextInt(); Mat[x][y]=Mat[y][x]=weight; } boolean[] Mark=new boolean[N+1]; ArrayList[] Children=new ArrayList[N+1]; for(int i=1;i<=N;i++) Children[i]=new ArrayList<Integer>(); ArrayList<Integer> Que=new ArrayList<Integer>(); Que.add(1); Mark[1]=true; int front=0; while(front<Que.size()) { int head=Que.get(front); front++; for(int j=1;j<=N;j++) if(Mat[head][j]!=-1 && Mark[j]==false) { Que.add(j); Mark[j]=true; Children[head].add(j); } } int[][] Apple=new int[N+1][Q+1]; for(int i=Que.size()-1;i>=0;i--) { int a=Que.get(i); if(Children[a].size()!=0) for(int q=1;q<=Q;q++) { int max=0; int x=(int) Children[a].get(0); int y=(int) Children[a].get(1); for(int q1=0;q1<=q;q1++) { int current; int q2=q-q1; if(q1==0) current=Apple[y][q2-1]+Mat[a][y]; else { current=Apple[x][q1-1]+Mat[a][x]; if(q2!=0) current+=Apple[y][q2-1]+Mat[a][y]; } if(current>max) max=current; } Apple[a][q]=max; } } System.out.println(Apple[1][Q]); } public static void main(String[] args) { Main main = new Main(); } }
    最新回复(0)