水库 (树形dp)

R国有n座城市和n-1条长度为1的双向道路,每条双向道路连接两座城市,城市之间均相互连通。现在你需要维护R国的供水系统。你可以在一些城市修建水库,在第i个城市修建水库需要每年c_i的维护费用。对于没有修建水库的城市,如果离它最近的水库的距离为d,那么需要每年t_i的运输费用来保证该城市的用水需求。保证t_i严格递增。你的任务是计算出每年所需要的最小花费。对于10%的数据,\(n<=5\)。对于30%的数据,\(n<=20\)。对于另外40%的数据,\(t_i=i\)。对于100%的数据,\(n<=1000\),\(c_i,t_i<=100000\)。

这可能算是我做的第一道树形dp?i表示以i为根的子树,j表示i的供水依赖于j。k为i的子节点。\(dp[i][j]=t[dis[now][j]]+c[j]+\sum min(dp[k][j]-c[j],best[k])\)。也就是说对于i的子树,要么i和k共用一个水库,要么用的水库不一样。如果是共用水库,说明水库不用重复建,那么建造水库的成本可以省掉。

但是我在思考过程中发现这样一种情况:

这个情况。。hjq大神说可以证明不存在。因为既然j也选了,t也选了,i一定是哪个更近选哪个。所以i一定不会选j。(被自己蠢哭了)

#include <cstdio>
#include <algorithm> const int maxn=1005, INF=1e9; class Graph{
public:
struct Edge{
int to, next; Graph *belong;
void set(int x, int y, Graph *g){
to=x; next=y; belong=g; }
Edge& operator ++(){
return *this=belong->edge[next]; }
inline int operator *(){ return to; }
};
void addedge(int x, int y){
edge[++cntedge].set(y, fir[x], this);
fir[x]=cntedge;
}
inline Edge& getlink(int x){ return edge[fir[x]]; }
private:
int cntedge, fir[maxn];
Edge edge[maxn*2];
}; int n, c[maxn], t[maxn];
int f[maxn][maxn], best[maxn];
int dis[maxn][maxn];
Graph g; void get_dis(int now, int step, int source, int pre){
dis[now][source]=dis[source][now]=step;
Graph::Edge e=g.getlink(now);
for (; *e; ++e) if (*e!=pre)
get_dis(*e, step+1, source, now);
} void dfs(int now, int par){
Graph::Edge e=g.getlink(now);
for (int j=1; j<=n; ++j) f[now][j]=t[dis[now][j]]+c[j];
for (; *e; ++e){
if (*e!=par) dfs(*e, now);
else continue;
for (int j=1; j<=n; ++j)
f[now][j]+=std::min(f[*e][j]-c[j], best[*e]);
}
for (int j=1; j<=n; ++j)
best[now]=std::min(best[now], f[now][j]);
} int main(){
scanf("%d", &n);
for (int i=1; i<=n; ++i) scanf("%d", &c[i]);
for (int i=1; i<=n; ++i) scanf("%d", &t[i]);
int x, y;
for (int i=1; i<n; ++i){
scanf("%d%d", &x, &y);
g.addedge(x, y); g.addedge(y, x);
}
for (int i=1; i<=n; ++i) get_dis(i, 0, i, 0);
std::fill(best, best+maxn, INF);
dfs(1, 0);
printf("%d\n", best[1]);
return 0;
}

水库(树形dp)的更多相关文章

  1. Fire (poj 2152 树形dp)

    Fire (poj 2152 树形dp) 给定一棵n个结点的树(1<n<=1000).现在要选择某些点,使得整棵树都被覆盖到.当选择第i个点的时候,可以覆盖和它距离在d[i]之内的结点,同 ...

  2. poj3417 LCA + 树形dp

    Network Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 4478   Accepted: 1292 Descripti ...

  3. COGS 2532. [HZOI 2016]树之美 树形dp

    可以发现这道题的数据范围有些奇怪,为毛n辣么大,而k只有10 我们从树形dp的角度来考虑这个问题. 如果我们设f[x][k]表示与x距离为k的点的数量,那么我们可以O(1)回答一个询问 可是这样的话d ...

  4. 【BZOJ-4726】Sabota? 树形DP

    4726: [POI2017]Sabota? Time Limit: 20 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 128  Solved ...

  5. 树形DP+DFS序+树状数组 HDOJ 5293 Tree chain problem(树链问题)

    题目链接 题意: 有n个点的一棵树.其中树上有m条已知的链,每条链有一个权值.从中选出任意个不相交的链使得链的权值和最大. 思路: 树形DP.设dp[i]表示i的子树下的最优权值和,sum[i]表示不 ...

  6. 树形DP

    切题ing!!!!! HDU  2196 Anniversary party 经典树形DP,以前写的太搓了,终于学会简单写法了.... #include <iostream> #inclu ...

  7. BZOJ 2286 消耗战 (虚树+树形DP)

    给出一个n节点的无向树,每条边都有一个边权,给出m个询问,每个询问询问ki个点,问切掉一些边后使得这些顶点无法与顶点1连接.最少的边权和是多少.(n<=250000,sigma(ki)<= ...

  8. POJ2342 树形dp

    原题:http://poj.org/problem?id=2342 树形dp入门题. 我们让dp[i][0]表示第i个人不去,dp[i][1]表示第i个人去 ,根据题意我们可以很容易的得到如下递推公式 ...

  9. hdu1561 The more, The Better (树形dp+背包)

    题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=1561 思路:树形dp+01背包 //看注释可以懂 用vector建树更简单. 代码: #i ...

随机推荐

  1. ListOperations

    RedisOperations<K,V> getOperations()  V index(K key, long index)  V leftPop(K key)  V leftPop( ...

  2. 给GridView删除列添加删除提示

         首先设置CommandField,把ShowEditButton.ShowDeleteButton属性都设置为true,也可以只设置ShowDeleteButton属性,那样下面的代码你要修 ...

  3. Docker与LXC、虚拟化技术的区别——虚拟化技术本质上是在模拟硬件,Docker底层是LXC,本质都是cgroups是在直接操作硬件

    先说和虚拟化技术的区别: 难道虚拟技术就做不到吗? 不不不,虚拟技术也可以做到,但是会有一定程度的性能损失,灵活度也会下降.容器技术不是模仿硬件层次,而是 在Linux内核里使用cgroup和name ...

  4. Java 集合常用特点

    1:集合:1) Collection(单列集合) ---------------------------------------------------------------------       ...

  5. 继续学习:C语言关键字

    auto :声明自动变量 break:跳出当前循环 case:开关语句分支 char :声明字符型变量或函数 const :声明只读变量 continue:结束当前循环,开始下一轮循环 default ...

  6. 股神小L

    题解 贪心 若当前手中还持有股,则一定会卖出去. 否则,考虑之前卖出的最便宜的股,若售价比当前的股高,就买下这个股,否则我们就把之前卖出的最便宜的股改为买入,这样一定会有股,然后再把这个股卖出即可. ...

  7. .net Core 2.1 MVC+EF+Redis搭建

    官方学习资料 搭建空MVC框架 1.创建一个空模板 2.创建文件夹 Controllers.Models.Views 3.在Controllers文件夹下创建HomeController.cs 选择C ...

  8. Java Modifiers

    Private means this could only be seen within this class. Protected means "package private" ...

  9. docker 容器内服务自启动

    centos6/7 有区别先说6 centos6: 方式一:rc.local + 容器内的启动脚本 1.chkconfig docker on #docker开机自启动2.[root@master y ...

  10. spring IOC 注解@Required

    @Required注解适用于bean属性的setter方法,使用@Required的方法必须在xml中填充,负责报错 例如下面的例子中,student中的setAge和setName有@Require ...