二叉苹果树

题目描述

有一棵苹果树,如果树枝有分叉,一定是分 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
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

callmeCassie

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值