二叉苹果树

题意/Description:

    有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点)

这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1。

我们用一根树枝两端连接的结点的编号来描述一根树枝的位置。下面是一颗有4个树枝的树

2 5

\ /

3 4

\ /

1

现在这颗树枝条太多了,需要剪枝。但是一些树枝上长有苹果。给定需要保留的树枝数量,求出最多能留住多少苹果。

读入/Input:

 
  第1行2个数,N和Q。 N表示在树枚举的点数。Q表示应保留的分支数量。

    下来N - 1行中包含分支的描述。每个描述包括三个整数用空格分开的。它们的前两个由它的结束点定义分支。第三个数字上定义这个分支苹果的数量。你可以假设没有分支包含超过30000苹果。

输出/Output:

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

题解/solution:

   这个题目都讲到了二叉了,很容易的想到树型DP。不讲废话,进入话题。

      如果只有一个容量,取左右两边最大值。  

        f[t,x]:=max(g[t,l[t]],g[t,r[t]]);

      如果大于一个容量,先设左右两边都被分配。

        f[t,x]:=max(f[t,x],f[l[t],i]+f[r[t],x-2-i]);

      然后只取左边或只取右边。 

       
f[t,x]:=max(f[t,x],f[l[t],x-1]+g[t,l[t]]); 或 f[t,x]:=max(f[t,x],f[r[t],x-1]+g[t,r[t]]);

代码/Code:

<strong>var
  n,q,o:longint;
  a,g,f:array [0..101,0..101] of longint;
  v:array [0..101] of boolean;
  l,r,du:array [0..101] of longint;
function max(t,k:longint):longint;
begin
  if t>k then exit(t);
  exit(k);
end;

procedure tree(x:longint);
var
  i:longint;
begin
  if x=0 then exit;
  v[x]:=true;
  for i:=1 to a[x,0] do
    if not v[a[x,i]] then
      if l[x]=0 then l[x]:=a[x,i]
                else r[x]:=a[x,i];
  tree(l[x]);
  tree(r[x]);
end;

procedure main(t,x:longint);
var
  i:longint;
begin
  if (x=0) or (t=0) then
    begin
      f[t,x]:=0;
      exit;
    end;
  if f[t,x]>0 then exit;
  if x=1 then
    begin
      f[t,x]:=max(g[t,l[t]],g[t,r[t]]);
      exit;
    end;
  for i:=0 to x-2 do
    begin
      main(l[t],i);
      main(r[t],x-2-i);
      f[t,x]:=max(f[t,x],f[l[t],i]+f[r[t],x-2-i]);
    end;
  f[t,x]:=f[t,x]+g[t,l[t]]+g[t,r[t]];
  main(l[t],x-1);
  f[t,x]:=max(f[t,x],f[l[t],x-1]+g[t,l[t]]);
  main(r[t],x-1);
  f[t,x]:=max(f[t,x],f[r[t],x-1]+g[t,r[t]]);
end;

procedure init;
var
  i,x,y,z:longint;
begin
  readln(n,q);
  for i:=1 to n-1 do
    begin
      readln(x,y,z);
      g[x,y]:=z; g[y,x]:=z;
      inc(a[x,0]); a[x,a[x,0]]:=y;
      inc(a[y,0]); a[y,a[y,0]]:=x;
    end;
  o:=1;
  for i:=1 to n do
    if a[i,0]=2 then
      begin
        o:=i;
        break;
      end;
end;

begin
  init;
  tree(o);
  main(o,q);
  write(f[o,q]);
end.
</strong>

时间: 2024-10-29 12:57:10

二叉苹果树的相关文章

二叉苹果树(树型DP+背包)

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

luogu P2015 二叉苹果树

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

二叉苹果树|codevs5565|luoguP2015|树形DP|Elena

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

[Luogu2015]二叉苹果树(树形dp)

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

luoguP2015 二叉苹果树

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

MZOJ 1134 &amp;&amp; LuoGu P2015 二叉苹果树

MZOJ 1134 && LuoGu P2015 二叉苹果树     [传送门] #include<bits/stdc++.h> using namespace std; const int maxn=500; int N,Q; int head[maxn],k=0; int w[maxn][maxn],f[maxn][maxn]; struct edge{ int v,w,nxt; }e[maxn<<1]; void init(){ freopen("i

二叉苹果树(由根分为左子树和右子树两部分情况)

有一棵二叉苹果树,如果数字有分叉,一定是分两叉,即没有只有一个儿子的节点.这棵树共  个节点,标号  至 ,树根编号一定为 . 我们用一根树枝两端连接的节点编号描述一根树枝的位置.一棵有四根树枝的苹果树,因为树枝太多了,需要剪枝.但是一些树枝上长有苹果,给定需要保留的树枝数量,求最多能留住多少苹果. 输入格式 第一行两个数 N和 Q,N 表示树的节点数, Q表示要保留的树枝数量. 接下来 N-1行描述树枝信息,每行三个整数,前两个是它连接的节点的编号,第三个数是这根树枝上苹果数量. 输出格式 输

洛谷—— P2015 二叉苹果树

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

洛谷 P2015 二叉苹果树

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