Fire (poj 2152 树形dp)
Fire (poj 2152 树形dp)
给定一棵n个结点的树(1<n<=1000)。现在要选择某些点,使得整棵树都被覆盖到。当选择第i个点的时候,可以覆盖和它距离在d[i]之内的结点,同时花费为v[i]。问最小花费。
以前做过一道类似的题(水库),这道题也差不多。首先来考虑,用\(best[i]\)表示以i为根的子树的最小花费。这样做有什么问题呢?它无法很好的处理消防站重复建的问题。
所以换一种做法。\(best[i]\)依然表示原来的含义,新建一个数组\(f[i][j]\),表示当i这个结点,依赖j的消防站时的最小花费。转移方程就是:\(f[i][j]=v[i]+\sum min(f[son_k][j]-v[j], best[son_k])\)。注意当\(dis(i, j)>d[i]\)时,\(f[i][j]=\infty\)。它的思想就是如果i依赖j,就直接让子树中依赖j的点都减去依赖,从而消除影响。
(傻逼了,用rmq求树上两点距离)
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=1005, maxm=1005, logn=12, INF=1e9;
struct Graph{
struct Edge{
int to, next, v; Graph *bel;
inline int operator*(){ return to; }
Edge& operator ++(){
return *this=bel->edge[next]; }
}edge[maxm*2];
void reset(){
memset(fir, 0, sizeof(fir)); cntedge=0; }
void addedge(int x, int y, int v){
Edge& e=edge[++cntedge];
e.to=y; e.next=fir[x]; e.v=v;
e.bel=this; fir[x]=cntedge; }
Edge& getlink(int x){ return edge[fir[x]]; }
int cntedge, fir[maxn];
}g;
//初始化及树形dp
int T, n, mi[logn], w[maxn], d[maxn];
int best[maxn], dp[maxn][maxn];
//求两点距离(rmq lca)
int id[maxn*2], fir[maxn], dep[maxn], time;
int st[maxn*2][logn];
void predfs(int now, int par){
Graph::Edge e=g.getlink(now);
id[++time]=now; fir[now]=time;
for (; *e; ++e){
if (*e==par) continue;
dep[*e]=dep[now]+e.v; predfs(*e, now);
id[++time]=now;
}
}
int mindep(int x, int y){
return (dep[x]<dep[y])?x:y; }
void init_st(){
for (int i=1; i<=n*2; ++i) st[i][0]=id[i];
for (int i=1; i<logn; ++i)
for (int j=1; j<=n*2; ++j) if (j+mi[i]-1<=n*2)
st[j][i]=mindep(st[j][i-1], st[j+mi[i-1]][i-1]);
}
int log2(float x){
return ((unsigned&)x>>23&255)-127;
}
int getlca(int x, int y){
if (fir[x]>fir[y]) swap(x, y);
int fx=fir[x], fy=fir[y];
int logxy=log2(fy-fx+1);
return mindep(st[fx][logxy],
st[fy-mi[logxy]+1][logxy]);
}
int dis(int x, int y){
int lca=getlca(x, y);
return dep[x]+dep[y]-2*dep[lca];
}
void dfs(int now, int par){
Graph::Edge e=g.getlink(now);
for (; *e; ++e) if (*e!=par) dfs(*e, now);
e=g.getlink(now); best[now]=INF;
for (int j=1; j<=n; ++j)
dp[now][j]=(dis(now, j)<=d[now]?w[j]:INF);
for (; *e; ++e) if (*e!=par)
for (int j=1; j<=n; ++j) if (dis(now, j)<=d[now])
dp[now][j]+=min(dp[*e][j]-w[j], best[*e]);
for (int j=1; j<=n; ++j)
best[now]=min(best[now], dp[now][j]);
}
int main(){
scanf("%d", &T); int x, y, l;
mi[0]=1; for (int i=1; i<logn; ++i) mi[i]=mi[i-1]*2;
while (T--){
g.reset(); scanf("%d", &n);
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){
scanf("%d%d%d", &x, &y, &l);
g.addedge(x, y, l); g.addedge(y, x, l);
}
time=0; predfs(1, 0); dep[1]=0;
init_st(); dfs(1, 0);
printf("%d\n", best[1]);
}
return 0;
}
Fire (poj 2152 树形dp)的更多相关文章
- poj 2152 树形DP
思路:这个没思路,看了陈启峰的论文写得. #include<map> #include<set> #include<cmath> #include<queue ...
- poj 1463(树形dp)
题目链接:http://poj.org/problem?id=1463 思路:简单树形dp,如果不选父亲节点,则他的所有的儿子节点都必须选,如果选择了父亲节点,则儿子节点可选,可不选,取较小者. #i ...
- poj 2486( 树形dp)
题目链接:http://poj.org/problem?id=2486 思路:经典的树形dp,想了好久的状态转移.dp[i][j][0]表示从i出发走了j步最后没有回到i,dp[i][j][1]表示从 ...
- poj 3140(树形dp)
题目链接:http://poj.org/problem?id=3140 思路:简单树形dp题,dp[u]表示以u为根的子树的人数和. #include<iostream> #include ...
- Strategic game(POJ 1463 树形DP)
Strategic game Time Limit: 2000MS Memory Limit: 10000K Total Submissions: 7490 Accepted: 3483 De ...
- POJ 2342 树形DP入门题
有一个大学的庆典晚会,想邀请一些在大学任职的人来參加,每一个人有自己的搞笑值,可是如今遇到一个问题就是假设两个人之间有直接的上下级关系,那么他们中仅仅能有一个来參加,求请来一部分人之后,搞笑值的最大是 ...
- poj 3345 树形DP 附属关系+输入输出(好题)
题目连接:http://acm.hust.edu.cn/vjudge/problem/17665 参考资料:http://blog.csdn.net/woshi250hua/article/detai ...
- POJ 1155 树形DP
题意:电视台发送信号给很多用户,每个用户有愿意出的钱,电视台经过的路线都有一定费用,求电视台不损失的情况下最多给多少用户发送信号. 转自:http://www.cnblogs.com/andre050 ...
- POJ 3342 树形DP+Hash
这是很久很久以前做的一道题,可惜当时WA了一页以后放弃了. 今天我又重新捡了起来.(哈哈1A了) 题意: 没有上司的舞会+判重 思路: hash一下+树形DP 题目中给的人名hash到数字,再进行运算 ...
随机推荐
- PAT天梯赛 L2-020. 功夫传人 【DFS】
题目链接 https://www.patest.cn/contests/gplt/L2-020 思路 从师父开始 一层一层往下搜 然后 搜到 得道者 就更新答案 AC代码 #include <c ...
- 虚拟化网络之OpenvSwitch
OpenvSwitch简称OVS,官网(http://openvswitch.org/) OVS是一个高质量.多层的虚拟交换软件,即虚拟交换机. OpenvSwitch的见的相关组件: ovs-vsw ...
- Spark- ERROR Shell: Failed to locate the winutils binary in the hadoop binary path java.io.IOException: Could not locate executable null\bin\winutils.exe in the Hadoop binaries.
运行 mport org.apache.log4j.{Level, Logger} import org.apache.spark.rdd.RDD import org.apache.spark.{S ...
- LoadRunner中的函数
函数是LoadRunner提供给性能测试工程师的利器,有了它,性能测试工程师可以对脚本进行更为自由的开发,更适应实际测试的需求,进一步扩展脚本的功能. LoadRunner函数的格式: 返回值 函数 ...
- nginx的fastcgi_param参数详解
在配置nginx的时候,有很多fastcgi_param参数,具体对应是什么值呢 引入:fastcgi_params 文件: fastcgi_params文件具体内容: postman 发送请求: n ...
- 网络编程学习笔记-TCP拥塞控制机制
为了防止网络的拥塞现象,TCP提出了一系列的拥塞控制机制.最初由V. Jacobson在1988年的论文中提出的TCP的拥塞控制由“慢启动(Slow start)”和“拥塞避免(Congestion ...
- bzoj 3522: Hotel dfs
题目大意 在无边权树上求三个点,使两两点的距离等.求方案数\((n\leq 5000)\) 题解 我们知道三个点在树上的关系只有两种 三点共链 三点不共连 (这不是废话吗) 我们发现三点共链肯定不满足 ...
- [转]addEventListener的第三个参数
如果要把HTML元素的事件与某个函数绑定起来,可以有下面三种方法,以最常见的“点击”事件为例. 方法一: 直接在对应的HTML元素标签上绑定函数 ? 1 <button id='submit' ...
- 用PCA降维 (Principal Component Analysis,主成分分析)
参考资料:Mastering Machine Learning With scikit-learn 降维致力于解决三类问题.第一,降维可以缓解维度灾难问题.第二,降维可以在压缩数据的同时让信息损失最 ...
- [原创]如何解决IE10下CkEditor报 --- SCRIPT5007: 无法获取未定义或 null 引用的属性“toLowerCase”
如何解决IE10下CkEditor报 --- SCRIPT5007: 无法获取未定义或 null 引用的属性“toLowerCase” 错误 如果你的IE是IE10,且不是运行在IE的兼容模式你也许会 ...