[poj2152]fire_树形dp
fire poj-2152
题目大意:给出一颗树,给出两个相邻节点的距离,以及每个节点的接受范围,还有当前节点的代价。我们想要求出覆盖整个图的最小代价。
注释:一个点被覆盖,当且仅当该点有防火站或者这个点的接受范围之内有防火站。计算两个不相邻节点的距离用LCA计算。节点数<=1000,接受范围<=10,000.
想法:poj最后一道树形dp,用这道神一样的树形dp结尾,在好不过。
对于一个节点来讲设几个状态:ans[pos]表示使以pos为根的子树被保护的最小代价。dp[pos][save]表示以pos为根的子树被保护的最小代价且pos节点必须被save节点保护。dist[i][j]表示i到j的距离。cost[i]表示在该节点建立防火站的代价。d[i]表示该节点的接受范围。
然后,我们考虑神奇的转移:$dp[u][v]=cost[v]+\sum min(dp[k][v]-cost[v],ans[k])$。这个状态的充要条件是k也可以被v覆盖。如果不然,我们就直接将dp[u][v]+=ans[k]。
最后,附上丑陋的代码... ...
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <queue> #define N 2100 using namespace std; const int inf=1e9; int cost[N],d[N],n; int dist[N][N]; int val[N]; int dp[N][N]; int head[N]; int ans[N]; int to[N]; int nxt[N]; int tot; queue<int>q; inline void add(int x,int y,int z) { to[++tot]=y; val[tot]=z; nxt[tot]=head[x]; head[x]=tot; } void get_dist(int dist[],int s) { dist[s]=0; q.push(s); while(q.size()) { int u=q.front(); q.pop(); for(int i=head[u];i;i=nxt[i]) { int v=to[i]; if(!dist[v]&&v!=s) { dist[v]=dist[u]+val[i]; q.push(v); } } } } void dfs(int pos,int fa) { for(int i=head[pos];i;i=nxt[i]) { if(to[i]==fa) continue; dfs(to[i],pos); } for(int v=1;v<=n;v++) { if(dist[pos][v]<=d[pos]) { int temp=0; for(int i=head[pos];i;i=nxt[i]) { int k=to[i]; if(k==fa) continue; temp+=min(dp[k][v]-cost[v],ans[k]); } dp[pos][v]=cost[v]+temp; } else dp[pos][v]=inf; } for(int i=1;i<=n;i++) { ans[pos]=min(ans[pos],dp[pos][i]); } } inline void original() { tot=0; memset(head,0,sizeof head); memset(dp,0,sizeof dp); memset(dist,0,sizeof dist); memset(ans,63,sizeof ans); } int main() { int cases; scanf("%d",&cases); while(cases--) { original(); scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&cost[i]); } for(int i=1;i<=n;i++) { scanf("%d",&d[i]); } int a,b,c; for(int i=1;i<n;i++) { scanf("%d%d%d",&a,&b,&c); add(a,b,c); add(b,a,c); } for(int i=1;i<=n;i++) { get_dist(dist[i],i); } dfs(1,0); printf("%d\n",ans[1]); } return 0; }
小结:太tm神了。其中,计算节点距离的处理是很巧妙地... ...
[poj2152]fire_树形dp的更多相关文章
- POJ2152 Fire (树形DP)
题意:n个城市n-1条边 组成一棵树 在每个城市修建消防站会有一个花费costi 每个城市能防火当且仅当地图上距离他最近的消防站距离小于di 问如何修建消防站 使地图上所有的城市都有预防火灾的能力 ...
- poj2152 Fire(树形DP)
题目链接:https://vjudge.net/problem/POJ-2152 题意:给定一颗大小为n的树,在每个结点建消防站花费为w[i],如果某结点没有消防站,只要在它距离<=d[i]的结 ...
- 树形DP小结
树形DP1.简介:树是一种数据结构,因为树具有良好的子结构,而恰好DP是从最优子问题更新而来,那么在树上做DP操作就是从树的根节点开始深搜(也就是记忆化搜索),保存每一步的最优结果.tips:树的遍历 ...
- 树形 DP 总结
树形 DP 总结 本文转自:http://blog.csdn.net/angon823/article/details/52334548 介绍 1.什么是树型动态规划 顾名思义,树型动态规划就是在“树 ...
- poj3417 LCA + 树形dp
Network Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 4478 Accepted: 1292 Descripti ...
- COGS 2532. [HZOI 2016]树之美 树形dp
可以发现这道题的数据范围有些奇怪,为毛n辣么大,而k只有10 我们从树形dp的角度来考虑这个问题. 如果我们设f[x][k]表示与x距离为k的点的数量,那么我们可以O(1)回答一个询问 可是这样的话d ...
- 【BZOJ-4726】Sabota? 树形DP
4726: [POI2017]Sabota? Time Limit: 20 Sec Memory Limit: 128 MBSec Special JudgeSubmit: 128 Solved ...
- 树形DP+DFS序+树状数组 HDOJ 5293 Tree chain problem(树链问题)
题目链接 题意: 有n个点的一棵树.其中树上有m条已知的链,每条链有一个权值.从中选出任意个不相交的链使得链的权值和最大. 思路: 树形DP.设dp[i]表示i的子树下的最优权值和,sum[i]表示不 ...
- 树形DP
切题ing!!!!! HDU 2196 Anniversary party 经典树形DP,以前写的太搓了,终于学会简单写法了.... #include <iostream> #inclu ...
随机推荐
- 使用Gulp进行代码压缩的步骤以及配置
一.安装步骤 1.首先确定是否安装了node.js,如果未安装,请先安装node.js: 2.确定是否安装了包管理工具npm,如未安装请安装:npm install npm -g: 3.安装gulp: ...
- 吐血整理:人工智能PDF中文教材资源包2.73G基本包含全部学习资料-人工智能学习书单
吐血整理:人工智能PDF中文教材资源包2.73G基本包含全部学习资料 人工智能学习书单(关注微信公众号:aibbtcom获取更多资源) 文末附百度网盘下载地址 人工神经网络与盲信号处理 人工神经网络与 ...
- 【BZOJ2882】工艺(后缀数组)
[BZOJ2882]工艺(后缀数组) 题面 BZOJ权限题,我爱良心洛谷 题解 最容易的想法: 把字符串在后面接一份 然后求后缀数组就行了... #include<iostream> #i ...
- ZJOI2007仓库建设
斜率优化 # include <stdio.h> # include <stdlib.h> # include <iostream> # include <s ...
- [BZOJ1014] [JSOI2008] 火星人prefix (splay & 二分答案)
Description 火星人最近研究了一种操作:求一个字串两个后缀的公共前缀.比方说,有这样一个字符串:madamimadam,我们将这个字符串的各个字符予以标号:序号: 1 2 3 4 5 6 7 ...
- IE浏览器右键菜单插件开发(上篇)——自定义一个IE右键菜单项
要做一个IE右键浏览器插件,得3步走. 第一,在IE右键菜单上添加自定义菜单名称,是通过注册表实现的,如下: string regkey = @"Software\Microsoft\Int ...
- angular路由详解四(子路由)
子路由是相对路由 路由配置部分: 主要是children const routes: Routes = [ {path:'home', component: HomeComponent, childr ...
- [Linux][Madplay播放器移植mini2440(ARM9)]
Madplay移植到mini2440全过程详解 madplay交叉编译 交叉编译器:arm-linux-gcc 3.4.1PC环境:RedHat-6 注意:最好在root权限下执行以下移植,否则在ma ...
- iframe结构的项目,登录页面嵌套
参考:http://www.cnblogs.com/qixin622/p/6548076.html 在网页编程时,我们经常需要处理,当session过期时,我们要跳到登陆页面让用户登陆,由于我们可能用 ...
- IIS前端页面不显示详细错误解决方法
要想解决这个问题,有三种方法可以考虑: 1.Internet信息服务(IIS)管理器 2.Web.config文件 3. 命令行 在IIS的"错误页"右边的"编辑功能设置 ...