poj2152 Fire(树形DP)
时间:2019-08-27
本文章向大家介绍poj2152 Fire(树形DP),主要包括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+5; 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<<1]; 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,0,0); best[u]=inf; for(int i=1;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=0; for(int i=1;i<=n;++i) head[i]=0; for(int i=1;i<=n;++i) scanf("%d",&w[i]); for(int i=1;i<=n;++i) scanf("%d",&d[i]); for(int i=1;i<n;++i){ int u,v,w; scanf("%d%d%d",&u,&v,&w); adde(u,v,w); adde(v,u,w); } dfs(1,0); printf("%d\n",best[1]); } return 0; }
原文地址:https://www.cnblogs.com/FrankChen831X/p/11419331.html
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 聊聊dubbo-go的metricsFilter
- 配置.gitignore
- 同样的GitHub包你就下载失败
- Linux编译C++
- 聊聊dubbo-go的tracingFilter
- JDBC - 第一天
- JavaSE - 排序算法
- JavaSE - 多态的本质
- Result Maps collection does not contain value for XXX 错误
- 当端口被占用如何kill占用端口的进程
- 将本地仓库同步到Github上的远程仓库
- 毫不留情地揭开 ArrayList 和 LinkedList 之间的神秘面纱
- 关于void QProcess::start参数问题的解决
- Python格式化输出
- 多线程 - 生产者消费者模式