首页 > 其他分享 >洛谷 P2015 二叉苹果树

洛谷 P2015 二叉苹果树

时间:2024-06-13 15:26:13浏览次数:16  
标签:洛谷 int P2015 树枝 二叉 条数 son 节点 dp

题目链接:二叉苹果树



思路

       本题使用链式向前星存储树上的边,然后DFS搜索+简单dp。
       dp数组,dp[i][j]表示节点i及其子树保留k根树枝得到的最大苹果数。son数组存储当前节点的孩子节点的编号和当前节点与孩子节点之间的树枝上的苹果个数。
       对于dp递推公式,我们可以对每一个节点逐个分析,对于每个节点,可以将剩下的树枝条数分给左子树和右子树,当剩下的树枝只分给左子树时只需要加上当前节点与左孩子之间的树枝上的苹果个数和dp[左孩子节点编号][剩下的树枝条数-1],即为dp[x][branchNumber] = dp[leftChild][branchNumber - 1] + appleNumber[x][leftChild],当剩下的树枝只分给右子树时只需要加上当前节点与右孩子之间的树枝上的苹果个数和dp[右孩子节点编号][剩下的树枝条数-1],即为dp[x][branchNumber] = dp[rightChild][branchNumber - 1] + appleNumber[x][rightChild],当左右子树都分到了树枝时,,需要加上当前节点和左右孩子之间的树枝上的苹果个数和dp[左孩子节点编号][剩下的树枝条数 - 2]、dp[右孩子节点编号][剩下的树枝条数 - 2],即为dp[x][branchNumber] = dp[leftChild][branchNumber - 2] + dp[rightChild][branchNumber - 2] + appleNumber[x][leftChild] + appleNumber[x][rightChild]


题解

#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 2e2 + 10;
int head[N], edge[N], amount[N], cnt, nex[N], dp[105][105], deep[N];
int n, q;

void add(int x, int y, int num) {
  nex[++cnt] = head[x];
  head[x] = cnt;
  edge[cnt] = y;
  amount[cnt] = num;
}

void dfs(int x, ll fa) {
  vector<pair<int, int>> son;
  for (int i = head[x]; i; i = nex[i]) {
    int to = edge[i], num = amount[i];
    // 当枚举到父节点时,跳过
    if (to == fa)
      continue;
    dfs(to, x);
    // 记录当前子节点的数据
    son.push_back({to, num});
  }
  // 当当前节点没有子节点为叶子节点时直接返回上级函数
  if (son.empty()) {
    return;
  }
  // 枚举当前节点剩下的树枝条数
  for (int i = 1; i <= q; i++) {
    // 枚举分给左子树的树枝条数
    for (int j = 0; j <= i; j++) {
      int num = 0;
      // 左子树树枝条数大于0时就需要先留下当前节点和左孩子之间的树枝才能将当前节点和左子树连接起来
      if (j > 0) {
        num += son[0].second;
      }
      // 左子树树枝条数大于0时就需要先留下当前节点和左孩子之间的树枝才能将当前节点和左子树连接起来
      if (i - j > 0) {
        num += son[1].second;
      }
      // 左子树树枝条数大于0时
      if (j != 0) {
        dp[x][i] = max(dp[x][i], dp[son[0].first][j - 1] + dp[son[1].first][i - j - 1] + num);
      } else {
        // 左子树条数等于0时,说明树枝全部分给了右子树
        dp[x][i] = max(dp[x][i], dp[son[1].first][i - j - 1] + num);
      }
    }
  }
}

int main() {
  cin >> n >> q;

  for (int i = 1; i < n; i++) {
    int a, b, c;
    cin >> a >> b >> c;
    // 添加边
    add(a, b, c);
    add(b, a, c);
  }

  dfs(1, 0);

  cout << dp[1][q];
  return 0;
}

标签:洛谷,int,P2015,树枝,二叉,条数,son,节点,dp
From: https://www.cnblogs.com/againss/p/18245936

相关文章

  • 二叉搜索树序列
    题目链接二叉搜索树序列题目描述注意点二叉搜索树中的节点数在[0,1000]的范围内1<=节点值<=10^6解答思路本题的题目解释成一句话也就是:每一个节点都必须排在其子孙节点的前面,同一层的节点可以任意排列首先想到的是广度优先遍历,将每一层的节点加入到一个List......
  • 二叉搜索树(待补充)
    二叉搜索树,是指一棵空树或者具有下列性质的二叉树:若任意节点的左子树不空,则左子树上所有节点的值均小于它的根节点的值;若任意节点的右子树不空,则右子树上所有节点的值均大于它的根节点的值;任意节点的左,右子树也分别为二叉搜索树;没有键值相等的节点。用Java来表示二叉树p......
  • 力扣刷题记录: 1339. 分裂二叉树的最大乘积
        本题是第174场周赛的Q3,LC竞赛分为1675.方法一.递归(超时)    单纯使用递归对每一个节点进行遍历,代码如下:classSolution{longlongans=-1;public:intmaxProduct(TreeNode*root){longlongtotal_sum=sum(root);......
  • 洛谷 P1352 没有上司的舞会
    题目链接:没有上司的舞会思路题解#include<bits/stdc++.h>usingnamespacestd;#definelllonglongconstintN=1e5+10;intdp[N][2],happy[N],subordinate[N],cnt,head[N],nex[N],edge[N];//链式向前星存储边voidadd(intx,inty){nex[++cnt]=......
  • 洛谷 P1219 八皇后
    题目链接:八皇后思路    这是一个典型的搜索题目,从前往后依次枚举行数,从第一行开始依次枚举皇后的纵坐标,并判断当前坐标是否满足题目要求,满足题目要求则标记将答案存储,并继续向下枚举下一行。由分析可得每条对角线上的任意一点的横纵坐标满足公式i-j+n的值与对角......
  • 洛谷P1601 A+B Problem(高精)
    #include<iostream>#include<string>#include<cstring>#include<cstdio>usingnamespacestd;constintN=1005;structbign{intlen,s[N];bign(){memset(s,0,sizeof(s));len=1;}bign(intnum){*this=num;}......
  • 【Test 66 】 高阶数据结构 二叉搜索树 必会知识点!
    文章目录1.二叉搜索树的概念2.二叉搜索树K模型的代码实现2.1Find()查找的实现2.2Insert()插入的实现2.3InOrder()中序遍历的实现2.4Erase()删除的实现3.二叉搜索树的KV模型4.二叉搜索树的性能分析1.二叉搜索树的概念......
  • Day49 代码随想录打卡|二叉树篇---二叉搜索树中的搜索
    题目(leecodeT700):给定二叉搜索树(BST)的根节点 root 和一个整数值 val。你需要在BST中找到节点值等于 val 的节点。返回以该节点为根的子树。如果节点不存在,则返回 null 。方法:递归法:本题考察了二叉搜索树的特性,二叉搜索树指的是在这个二叉树中,他的每一个根节点......
  • 验证二叉搜索树-力扣
    第一次做这道题时,想的解法是递归去判断比较左节点小于中间节点,右节点大于中间节点,而这恰恰进入了陷阱,这道题不仅仅是判断子树是否左节点小于中间节点,右节点大于中间节点;要比较的是左子树所有节点小于中间节点,右子树所有节点大于中间节点。附上错误代码:classSolution{pu......
  • 五分钟“手撕”二叉树
    代码放开头,供大家查阅。但是对于树来说,更重要的是理解树的概念,树的概念很多,题却是千篇一律,这篇博客详细的讲解了概念,看完必有很大的收获。 目录一、实现代码二、什么是树三、树的重要概念四、什么是二叉树 二叉树概念:特殊的二叉树: 1.满二叉树:2.完全二叉树:......