poj2152 Fire(树形DP)
题目链接:https://vjudge.net/problem/POJ-2152
题意:给定一颗大小为n的树,在每个结点建消防站花费为w[i],如果某结点没有消防站,只要在它距离<=d[i]的结点有消防站即可,求最小花费。
思路:
好难的树形dp,一点思绪也木有,只能搜题解。
用dp[u][i]表示以u为根的子树满足条件,并且结点u依赖于结点i的最小花费。用best[u]表示以u根的子树满足条件的最小花费,那么best[u]=min(dp[u][i])。
求best[u]时,先跑一遍dfs得到所有结点距离u的距离dis[i]。如果dis[i]>d[u],那么u没法依赖i,此时dp[u][i]=inf。否则dis[i]<=d[u],此时dp[u][i]=w[i]+sum( min( best[v] , dp[v][i]-w[i] ) ),其中i从1遍历到n,v是u的子结点。因为v的依赖有两种情况,如果v依赖于以v为根的子树中的结点,即best[v]; 如果v依赖于其余的结点,那么一定是i。反证一下,如果v依赖于k,那么u也一定依赖于k。所以应取best[v]和dp[v][i]-w[i]的最小值,减w[i]是因为w[i]多加了一次。
AC代码:
#include<cstdio>
#include<algorithm>
using namespace std; const int maxn=1e3+;
const int inf=0x3f3f3f3f;
int T,n,cnt,head[maxn],w[maxn],d[maxn],dp[maxn][maxn],dis[maxn];
int best[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 getdis(int u,int fa,int len){
dis[u]=len;
for(int i=head[u];i;i=edge[i].nex){
int v=edge[i].v;
if(v==fa) continue;
getdis(v,u,len+edge[i].w);
}
} 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);
}
getdis(u,,);
best[u]=inf;
for(int i=;i<=n;++i){
if(dis[i]>d[u]) dp[u][i]=inf;
else{
dp[u][i]=w[i];
for(int j=head[u];j;j=edge[j].nex){
int v=edge[j].v;
if(v==fa) continue;
dp[u][i]+=min(best[v],dp[v][i]-w[i]);
}
}
best[u]=min(best[u],dp[u][i]);
}
} int main(){
scanf("%d",&T);
while(T--){
scanf("%d",&n);
cnt=;
for(int i=;i<=n;++i)
head[i]=;
for(int i=;i<=n;++i)
scanf("%d",&w[i]);
for(int i=;i<=n;++i)
scanf("%d",&d[i]);
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(,);
printf("%d\n",best[]);
}
return ;
}
poj2152 Fire(树形DP)的更多相关文章
- POJ2152 Fire (树形DP)
题意:n个城市n-1条边 组成一棵树 在每个城市修建消防站会有一个花费costi 每个城市能防火当且仅当地图上距离他最近的消防站距离小于di 问如何修建消防站 使地图上所有的城市都有预防火灾的能力 ...
- [poj2152]fire_树形dp
fire poj-2152 题目大意:给出一颗树,给出两个相邻节点的距离,以及每个节点的接受范围,还有当前节点的代价.我们想要求出覆盖整个图的最小代价. 注释:一个点被覆盖,当且仅当该点有防火站或者这 ...
- POJ 2152 Fire(树形DP)
题意: 思路:令F[i][j]表示 的最小费用.Best[i]表示以i为根节点的子树多有节点都找到负责消防站的最小费用. 好难的题... #include<algorithm> #incl ...
- Fire (poj 2152 树形dp)
Fire (poj 2152 树形dp) 给定一棵n个结点的树(1<n<=1000).现在要选择某些点,使得整棵树都被覆盖到.当选择第i个点的时候,可以覆盖和它距离在d[i]之内的结点,同 ...
- POJ 2152 Fire (树形DP,经典)
题意:给定一棵n个节点的树,要在某些点上建设消防站,使得所有点都能够通过某个消防站解决消防问题,但是每个点的建站费用不同,能够保证该点安全的消防站的距离上限也不同.给定每个点的建站费用以及最远的消防站 ...
- 树形 DP 总结
树形 DP 总结 本文转自:http://blog.csdn.net/angon823/article/details/52334548 介绍 1.什么是树型动态规划 顾名思义,树型动态规划就是在“树 ...
- 【转】【DP_树形DP专辑】【9月9最新更新】【from zeroclock's blog】
树,一种十分优美的数据结构,因为它本身就具有的递归性,所以它和子树见能相互传递很多信息,还因为它作为被限制的图在上面可进行的操作更多,所以各种用于不同地方的树都出现了,二叉树.三叉树.静态搜索树.AV ...
- 【DP_树形DP专题】题单总结
转载自 http://blog.csdn.net/woshi250hua/article/details/7644959#t2 题单:http://vjudge.net/contest/123963# ...
- 树形dp总结
转自 http://blog.csdn.net/angon823 介绍 1.什么是树型动态规划 顾名思义,树型动态规划就是在"树"的数据结构上的动态规划,平时作的动态规划都是线性的 ...
随机推荐
- Luogu P2516 [HAOI2010]最长公共子序列 DP
首先$LIS$显然:$f[i][j]=max(f[i][j-1],f[i-1][j],(a[i]==b[j])*f[i-1][j-1])$ 考虑如何转移数量: 首先,不管$a[i]$是否等于$b[j] ...
- JAVA实现四则运算的简单计算器
开发环境eclipse java neon. 今天用JAVA的swing界面程序设计制作了一个四则运算的简易计算器.代码以及截图如下: computer.java: ///////////////// ...
- CaoHaha's staff (HDU 6154)(2017中国大学生程序设计竞赛 - 网络选拔赛)
Problem Description "You shall not pass!" After shouted out that,the Force Staff appered i ...
- vue-element-admin平时使用归纳
message提示的使用 import { Message } from 'element-ui'; Message({ message: res.data.message || 'Error', t ...
- Win10 + CLion + 树莓派 + QT 远程开发调用Python
原则:能在一个机器上开发的就不在两台机器上!! 首先需要配置远程QT开发环境 配置Cmake cmake_minimum_required(VERSION 3.14) project(qt_test) ...
- python合并两个字典
1.借助dict(d1.items() + d2.items())的方法 2.借助字典的update()方法,没有返回值 3.借助字典的dict(d1, **d2)方法 4.d3={**d1,**d2 ...
- 预处理、const、static与sizeof-使用const与#define的特点及区别
1:#define只是用来做文本替换的.例如: #define PI 3.1415926 float angle; angle=*PI/; 那么,程序进行编译的时候,编译器会首先将“#define P ...
- Leetcode题目152.乘积最大子序列(动态规划-中等)
题目描述: 给定一个整数数组 nums ,找出一个序列中乘积最大的连续子序列(该序列至少包含一个数). 示例 1: 输入: [2,3,-2,4] 输出: 6 解释: 子数组 [2,3] 有最大乘积 6 ...
- centos7修改默认启动模式(图形/命令行)
centos7以后是这样的,7以前就是别的版本了 1.systemctl get-default命令获取当前模式 2.systemctl set-default graphical.target 修改 ...
- 如何快速查找到HTML头尾对应标签?
在使用Atom编辑器整理HTML代码的时候,希望快速找到HTML头尾对应的标签. ctrl+m 试试看