URAL-1018 Binary Apple Tree---树形DP
2024-08-27 06:13:06
题目链接:
https://cn.vjudge.net/problem/URAL-1018
题目大意:
给你一棵树,每条边有一个边权,求以1为根节点,q条边的子数(q+1个点),边权和至最大。
解题思路:
dp[root][j], 表示以root为根节点,保留j个节点的最大边权和。
dp[root][j]=max(dp[root][j],dp[root][j-t]+dp[son][t]+len);
t的范围从1到j - 1,因为每个点从dp[][1]开始更新
#include<bits/stdc++.h>
using namespace std;
const int maxn = + ;
typedef long long ll;
struct node
{
int v, w;
node(){}
node(int v, int w):v(v), w(w){}
};
vector<node>Map[maxn];
int num[maxn];//num[i]表示以i节点为root的子树中的点的数目
int dp[maxn][maxn];//dp[i][j]表示以i节点为root的子树中只有j条边最大权值
void dfs(int root, int fa)
{
num[root] = ;
for(int i = ; i < Map[root].size(); i++)
{
int v = Map[root][i].v, w = Map[root][i].w;
if(v == fa)continue;//不可回溯
dfs(v, root);//先将儿子信息更新好
num[root] += num[v];//root子树中当前的节点数目
for(int j = num[root]; j >= ; j--)//更新父节点的dp
{
for(int k = ; k < j && k <= num[v]; k++)//k不能等于j,k=j时说明root的点数目为0
dp[root][j] = max(dp[root][j], dp[root][j - k] + dp[v][k] + w);
}
}
}
int main()
{
int n, k;
while(scanf("%d%d", &n, &k) != EOF)
{
memset(dp, , sizeof(dp));
for(int i = ; i < n; i++)
{
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
Map[u].push_back(node(v, w));
Map[v].push_back(node(u, w));
}
dfs(, -);
cout<<dp[][k + ]<<endl;//包含k条边,也就是k+1个点
}
return ;
}
最新文章
- C语言新文法
- 数据库dump导入
- cmd 窗口配置mysql数据库
- SQLite的37个核心函数
- JPA概要
- 使用MWC四轴起飞侧翻解决方法
- Codeforces Round #254 (Div. 2) DZY Loves Chemistry【并查集基础】
- MongoDB的.Net驱动
- Java关键字transient和volatile小结(转)
- Java中StringBuffer类append方法的使用
- EntityFrameWork实现部分字段获取和修改(含源码)
- dojo中表格行隐藏出错
- 【55】java异常机制剖析
- error: src refspec XXX matches more than one
- [SDOI2013] 直径
- Oracle之with as和update用法
- 图之强连通、强连通图、强连通分量 Tarjan算法
- nodejs+mysql入门实例(增)
- AtomicBoolean
- js冒泡法和数组转换成字符串