[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 ...
随机推荐
- Rwordseg使用
#用于下载安装rJava 和 Rwordseg,如果安装了就注释掉 install.packages("rJava") install.packages("Rwordse ...
- JavaScript通过ID和name设置样式
JavaScript通过ID和name设置样式 1.说明 (1)根据所提供的元素的id值,返回对该元素的引用或节点 document.getElementById("tr_th") ...
- Caused by:java.sql.SQLException:ORA-01008:并非所有变量都已绑定
1.错误描述 Caused by:java.sql.SQLException:ORA-01008:并非所有变量都已绑定 2.错误原因 3.解决办法
- PC响应式、固宽布局思想
截止目前,国内绝大多数内容为主的网站(知乎,果壳,V2EX,网易新闻等)均使用内容区定宽布局,大多数电商网站(网易考拉,京东,聚美优品)也使用了内容区定宽的布局,也有些网站使用了自适应布局. 如果不明 ...
- Tomcat下使用C3P0配置JNDI数据源(在项目的META-INF目录下创建context.xml的文件)
一.C3P0下载 C3P0下载地址:http://sourceforge.net/projects/c3p0/files/?source=navbar 下载完成之后得到一个压缩包
- 【2016北京集训测试赛】azelso
[吐槽] 首先当然是要orzyww啦 以及orzyxq奇妙顺推很强qwq 嗯..怎么说呢虽然说之前零零散散做了一些概d的题目但是总感觉好像并没有弄得比较明白啊..(我的妈果然蒟蒻) 这题的话可以说是难 ...
- error:Unterminated <form:form tag
问题:标签不对称 解决:<form:form></form> 改成 <form:form> </form:form> 虽然又是自动补全带来的bug,但还 ...
- 进程优化工具Process Lasso Pro 8.4官方版+激活破解方法
Process Lasso是一款来自美国的系统进程优化工具,基于特殊算法动态调整进程的优先级别,通过合理的设置进程优先级来实现降低系统负担的功能.可有效避免蓝 屏.假死.进程停止响应.进程占用 CPU ...
- 谁能用通俗的语言解释一下什么是 RPC 框架?
转载自知乎:https://www.zhihu.com/question/25536695 知乎上很多问题的答案还是很好的,R大就经常在上面回答问题 关于RPC你的题目是RPC框架,首先了解什么叫RP ...
- python select模块详解
要理解select.select模块其实主要就是要理解它的参数, 以及其三个返回值.select()方法接收并监控3个通信列表, 第一个是所有的输入的data,就是指外部发过来的数据,第2个是监控和接 ...