题目链接:https://vjudge.net/problem/HDU-4003

题意:给一棵边权树,在树根s有m个人,要通过m个人遍历到所有点,一个人经过一条边花费为边的权值,求最小花费(可以走已经走过的边)。

思路:

  状态比较好想,用dp[u][j]表示在u结点的子树中有j个人的最小花费。但转移方程有点难想。

  重要的是怎么处理dp[u][0],对dp[v][0],即在v结点的子树中有0个人的最小花费,那么只能通过v的父结点u过来机器人,假设来x个人,那这x个人在遍历v子树所有点之后还要回到u才行,那么花费为2*sum[v]+2k*w,sum[v]是v子树中所有边的权值和,w是u->v的边权,所以k=1时花费最小,花费为2*sum[v]+2*w。故dp[u][0]=sum(2*sum[v],2*w),外面的sum表示求和。

  j>0时,可以简单地推出:dp[u][j]=min(dp[u][j] , dp[u][j-k]+dp[v][k]+k*w),v是u的子结点,k表示子结点v有k个人,w是u->v的边权。

AC代码:

#include<cstdio>
#include<algorithm>
using namespace std; const int maxn=1e4+;
const int inf=0x3f3f3f3f;
int n,s,m,cnt,head[maxn],sum[maxn],dp[maxn][]; struct node{
int v,w,nex;
}edge[maxn<<]; void adde(int u,int v,int w){
edge[++cnt].v=v;
edge[cnt].w=w;
edge[cnt].nex=head[u];
head[u]=cnt;
} void dfs(int u,int fa){
for(int i=head[u];i;i=edge[i].nex){
int v=edge[i].v;
if(v==fa) continue;
dfs(v,u);
for(int j=m;j>=;--j)
for(int k=;k<=j;++k)
if(k) dp[u][j]=min(dp[u][j],dp[u][j-k]+dp[v][k]+k*edge[i].w);
else dp[u][j]+=dp[v][]+*edge[i].w;
}
} int main(){
while(~scanf("%d%d%d",&n,&s,&m)){
cnt=;
for(int i=;i<=n;++i){
head[i]=;
for(int j=;j<=m;++j)
dp[i][j]=;
}
for(int i=;i<n;++i){
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
adde(u,v,w);
adde(v,u,w);
}
dfs(s,);
printf("%d\n",dp[s][m]);
}
return ;
}

hdoj4003 (树形dp+分组背包)的更多相关文章

  1. HDU4003Find Metal Mineral[树形DP 分组背包]

    Find Metal Mineral Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Other ...

  2. HDU-1011 Starship Troopers (树形DP+分组背包)

    题目大意:给一棵有根带点权树,并且给出容量.求在不超过容量下的最大权值.前提是选完父节点才能选子节点. 题目分析:树上的分组背包. ps:特判m为0时的情况. 代码如下: # include<i ...

  3. Ural-1018 Binary Apple Tree(树形dp+分组背包)

    #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #i ...

  4. hdu 1561 树形dp+分组背包

    题意:就是给定n个点,每个地点有value[i]的宝物,而且有的宝物必须是另一个宝物取了才能取,问取m个点可以获得的最多宝物价值. 一个子节点就可以返回m个状态,每个状态表示容量为j(j<=m) ...

  5. 【P2015】二叉苹果树 (树形DP分组背包)

    题目描述 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点) 这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1. 现在这颗树枝条太多了,需要剪枝.但是 ...

  6. poj2486 Apple Tree (树形dp+分组背包)

    题目链接:https://vjudge.net/problem/POJ-2486 题意:一棵点权树,起点在1,求最多经过m条边的最大点权和. 思路: 树形dp经典题.用3维状态,dp[u][j][0/ ...

  7. hdu1561 The more, The Better 树形DP+分组背包

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1561 思路: 典型的树形背包题目: 定义dp[i][j]表示以i为根节点,攻打j个城堡的获得的财宝的最 ...

  8. hdu 4003 树形dp+分组背包 2011大连赛区网络赛C

    题意:求K个机器人从同一点出发,遍历所有点所需的最小花费 链接:点我 Sample Input 3 1 1 //3个点,从1出发,1个机器人 1 2 1 1 3 1 3 1 2 1 2 1 1 3 1 ...

  9. HDU-4003 Find Metal Mineral (树形DP+分组背包)

    题目大意:用m个机器人去遍历有n个节点的有根树,边权代表一个机器人通过这条边的代价,求最小代价. 题目分析:定义状态dp(root,k)表示最终遍历完成后以root为根节点的子树中有k个机器人时产生的 ...

随机推荐

  1. Excel2013下拉框选择自动填充颜色

    图一写判断公式,图二选择应用范围.

  2. background-size值为cover和值为100%的区别

    background-size:100% 100%;---按容器比例撑满,图片变形: background-size:cover;---把背景图片放大到适合元素容器的尺寸,图片比例不变. IE8及以下 ...

  3. [Luogu] 树状数组

    https://www.luogu.org/problemnew/show/P3374 单点修改,区间查询 #include <iostream> #include <cstdio& ...

  4. Break Standard Weight (ZOJ 3706)

    Problem The balance was the first mass measuring instrument invented. In its traditional form, it co ...

  5. python数据分析与应用

    python数据分析与应用笔记 使用sklearn构建模型 1.使用sklearn转换器处理数据 import numpy as np from sklearn.datasets import loa ...

  6. 在Winform中屏蔽UnityWebPlayer的右键以及自带Logo解决方案整理

    根据项目的需要,对已经完成的Unity三维模型以及游戏要使用Winform进行包装,也就是使用Winform做一层外壳.因此在展示Unity的时候使用到了UnityWebPlayer这个插件,对于此插 ...

  7. Python 学习 —— 进阶篇(装饰器、类的特殊方法)

    Python基础部分学完之后,在进入其OOP部分前,先理解一下其装饰器这种结构,其功能可类比于Java中的面向切面编程,下面参见具体实例: def log(f): def fn(x): print ' ...

  8. 官网引用的axios,lodash文件在脚手架中如何使用?

    对于官网属性与侦听器模块,所引用的以下文件在脚手架中如何使用? <script src="https://cdn.jsdelivr.net/npm/axios@0.12.0/dist/ ...

  9. LC 898. Bitwise ORs of Subarrays

    We have an array A of non-negative integers. For every (contiguous) subarray B = [A[i], A[i+1], ..., ...

  10. python实现并发服务器实现方式(多线程/多进程/select/epoll)

    python实现并发服务器实现方式(多线程/多进程/select/epoll)   并发服务器开发 并发服务器开发,使得一个服务器可以近乎同一时刻为多个客户端提供服务.实现并发的方式有多种,下面以多进 ...