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.什么是树型动态规划 顾名思义,树型动态规划就是在"树"的数据结构上的动态规划,平时作的动态规划都是线性的 ...
随机推荐
- Java数据库小项目00---基础知识
目录 JDBC的简单使用 向JDBC注入攻击 防止注入攻击 自建JDBC工具类 自建工具类优化--使用配置文件 使用数据库连接池优化工具类 JDBC的简单使用 package Test; import ...
- 7.19T2
小 B 的树 题目背景及题意 小 B 有一颗树,它的形态与 OI 中的树相同,有 n 个节点,n-1 条边,每条边长度为 1 随着时间的流逝这棵树长大了,每条边有 50%的概率长度变为 2 小 B ...
- javascript数据结构之队列
首先什么是队列? 排队买东西就是生活中队列的实际例子,在队伍中大家必须按照顺序来,不能插队,新来的人只能排在队伍的最后面.新加入的人相当于队列的后端加入的元素,队伍最前面买完东西的人离开队伍相当于是队 ...
- [vim]多行注释和多行删除
vim中多行注释和多行删除命令,这些命令也是经常用到的一些小技巧,可以大大提高工作效率. 1.多行注释: 首先按esc进入命令行模式下,按下Ctrl + v,进入列(也叫区块)模式; 在行首使用上下键 ...
- 前端工程师需要掌握的 Babel 知识
在前端圈子里,对于 Babel,大家肯定都比较熟悉了.如果哪天少了它,对于前端工程师来说肯定是个噩梦.Babel 的工作原理是怎样的可能了解的人就不太多了.本文将主要介绍 Babel 的工作原理以及怎 ...
- Mongodb内存管理和使用情况查询
overview MongoDB使用的是内存映射存储引擎,即Memory Mapped Storage Engine,简称MMAP.MMAP可以把磁盘文件的一部分或全部内容直接映射到内存,这样文件中的 ...
- linux中wget未找到命令
(转)linux中wget未找到命令 转:https://blog.csdn.net/djj_alice/article/details/80407769 在装数据库的时候发现无法使用wget命令 ...
- Python中调用shell
1 简单调用shell命令 os.system(command) 在一个子shell中运行command命令, 并返回command命令执行完毕后的退出状态. 这实际上是使用C标准库函数system( ...
- Flutter移动电商实战 --(13)ADBanner组件的编写
1.AdBanner组件的编写 我们还是把这部分单独出来,需要说明的是,这个Class你也是可以完全独立成一个dart文件的.代码如下: 广告图片 class AdBanner extends Sta ...
- springmvc快速入门(注解版本)
1)springmvc快速入门(传统版) 步一:创建springmvc-day02这么一个web应用 步二:导入springioc,springweb和springmvc相关的jar包 ------- ...