【树形DP】【P1364】医院放置
Description
设有一棵二叉树,如图:

其中,圈中的数字表示结点中居民的人口。圈边上数字表示结点编号,现在要求在某个结点上建立一个医院,使所有居民所走的路程之和为最小,同时约定,相邻接点之间的距离为1。如上图中,
若医院建在1 处,则距离和=4+12+2*20+2*40=136;若医院建在3 处,则距离和=4*2+13+20+40=81……
Input
第一行一个整数n,表示树的结点数。
接下来的n行每行描述了一个结点的状况,包含三个整数,整数之间用空格(一个或多个)分隔,其中:第一个数为居民人口数;第二个数为左链接,为0表示无链接;第三个数为右链接。
Output
一个整数,表示最小距离和。
Sample Input
Sample Output
Hint
n≤100
Solution
事实上这是一道非常简单的全员最短路,直接floyd就能够AC,但是冲着DP的标签,有一种树形DP的方法,在常规的树形DP中,由儿子更新父亲的信息,但在本题中,需要预处理根节点的信息,然后通过父亲更新儿子。复杂度O(n)。
记f[i]为在i点放医院的答案,sz[i]为以i为根的子树的节点权值和,手动画图可推知,f[son]=f[fa]+(sz[1]-sz[to])-sz[to]=f[fa]+sz[1]-2*sz[to]。预处理f[1],dfs更新子树即可
Code
#include<cstdio>
#define maxn 105 inline void qr(int &x) {
char ch=getchar();int f=;
while(ch>''||ch<'') {
if(ch=='-') f=-;
ch=getchar();
}
while(ch>=''&&ch<='') x=(x<<)+(x<<)+(ch^),ch=getchar();
x*=f;
} inline int max(int a,int b) {return a>b?a:b;}
inline int min(int a,int b) {return a<b?a:b;}
inline int abs(int x) {return x<?-x:x;} inline void swap(int &a,int &b) {
int c=a;a=b;b=c;
} struct Edge {
int to,nxt;
};
Edge edge[maxn];int hd[maxn],ecnt;
inline void cont(int from,int to) {
edge[++ecnt].to=to;
edge[ecnt].nxt=hd[from];
hd[from]=ecnt;
} int n,num[maxn],a,sz[maxn],frog[maxn],deepth[maxn],ans; void dfs(int fa,int k) {
deepth[k]=deepth[fa]+;sz[k]=num[k];
if(!hd[k]) return;
for(int i=hd[k];i;i=edge[i].nxt) {
dfs(k,edge[i].to);
sz[k]+=sz[edge[i].to];
}
} void search(int k) {
for(int i=hd[k];i;i=edge[i].nxt) {
int &to=edge[i].to;
frog[to]=frog[k]+sz[]-*sz[to];
search(to);
}
ans=min(ans,frog[k]);
} int main() {
qr(n);
for(int i=;i<=n;++i) {
qr(num[i]);
a=;qr(a);
if(a) cont(i,a);
a=;qr(a);
if(a) cont(i,a);
}
deepth[]=-;
dfs(,);
for(int i=;i<=n;++i) frog[]+=num[i]*deepth[i];
ans=frog[];
search();
printf("%d\n",ans);
return ;
}
Summary
1、对于一般的树形DP,其状态设计一般为“以i为根的子树……”,通过儿子更新父亲。但是有一些特殊的DP形式,需要通过父亲更新儿子,f[i]表示“在i点……”。
2、对于树上的题,可以优先思考图论问题,然后再思考DP,有些题使用图论可以轻松解决。
【树形DP】【P1364】医院放置的更多相关文章
- BZOJ 2314: 士兵的放置( 树形dp )
树形dp... dp(x, 0)表示结点x不放士兵, 由父亲控制: dp(x, 1)表示结点x不放士兵, 由儿子控制: dp(x, 2)表示结点x放士兵. ---------------------- ...
- 【BZOJ2314】士兵的放置 树形DP
[BZOJ2314]士兵的放置 Description 八中有N个房间和N-1双向通道,任意两个房间均可到达.现在出了一件极BT的事,就是八中开始闹鬼了.老大决定加强安保,现在如果在某个房间中放一个士 ...
- 『战略游戏 最大利润 树形DP』
通过两道简单的例题,我们来重新认识树形DP. 战略游戏(luoguP1026) Description Bob喜欢玩电脑游戏,特别是战略游戏.但是他经常无法找到快速玩过游戏的办法.现在他有个问题.他要 ...
- 树形dp 入门
今天学了树形dp,发现树形dp就是入门难一些,于是好心的我便立志要发一篇树形dp入门的博客了. 树形dp的概念什么的,相信大家都已经明白,这里就不再多说.直接上例题. 一.常规树形DP P1352 没 ...
- 【BZOJ2616】SPOJ PERIODNI 笛卡尔树+树形DP
[BZOJ2616]SPOJ PERIODNI Description Input 第1行包括两个正整数N,K,表示了棋盘的列数和放的车数. 第2行包含N个正整数,表示了棋盘每列的高度. Output ...
- [洛谷P2016] 战略游戏 (树形dp)
战略游戏 题目描述 Bob喜欢玩电脑游戏,特别是战略游戏.但是他经常无法找到快速玩过游戏的办法.现在他有个问题. 他要建立一个古城堡,城堡中的路形成一棵树.他要在这棵树的结点上放置最少数目的士兵,使得 ...
- 树形DP小结
树形DP1.简介:树是一种数据结构,因为树具有良好的子结构,而恰好DP是从最优子问题更新而来,那么在树上做DP操作就是从树的根节点开始深搜(也就是记忆化搜索),保存每一步的最优结果.tips:树的遍历 ...
- 初涉树形dp
算是一个……复习以及进阶? 什么是树形dp 树形dp是一种奇妙的dp…… 它的一个重要拓展是和各种树形的数据结构结合,比如说在trie上.自动机上的dp. 而且有些时候还可以拓展到环加外向树.仙人掌上 ...
- P2016 战略游戏 (树形DP)
题目描述 Bob喜欢玩电脑游戏,特别是战略游戏.但是他经常无法找到快速玩过游戏的办法.现在他有个问题. 他要建立一个古城堡,城堡中的路形成一棵树.他要在这棵树的结点上放置最少数目的士兵,使得这些士兵能 ...
随机推荐
- RabbitMQ基础教程之使用进阶篇
RabbitMQ基础教程之使用进阶篇 相关博文,推荐查看: RabbitMq基础教程之安装与测试 RabbitMq基础教程之基本概念 RabbitMQ基础教程之基本使用篇 I. 背景 前一篇基本使用篇 ...
- 【20180807模拟测试】tree
题目描述 或许会传送失败的传送门 #分析 考虑如何才能让白边显得更(不)重要,即在每条白边上(加上)减去一个值. 我们可以二分这个值,然后用寻常方法做最小生成树.统计在此最小生成树里有多少白 边. 然 ...
- 地牢逃脱(BFS(广度优先搜索))
题目描述 给定一个 n 行 m 列的地牢,其中 '.' 表示可以通行的位置,'X' 表示不可通行的障碍,牛牛从 (x0 , y0 ) 位置出发,遍历这个地牢,和一般的游戏所不同的是,他每一步只能按照一 ...
- nginx 应用篇
nginx 信号控制(commanLine) kill singel pid ps aux|grep nginx nginx 有两个进程,一个 master 一个worker 一个master管理一 ...
- aishell数据处理为thchs30格式
目录 aishell数据转换格式 aishell数据转化方法 aishell数据格式对于用神经网络处理数据的同学来说比较不友善,因为他只有文字转录和音素级别的转录,并没有拼音的转录. 而thchs30 ...
- leetcode个人题解——#15 3sums
class Solution { public: vector<vector<int>> threeSum(vector<int>& nums) { sor ...
- STM32F4 编程手册学习1_编程模型
STM32F4 programming manual_1 1. 处理器模式与特权等级 处理器模式分为以下两种: 线程模式: 用来执行应用软件: 处理器从reset出来时,进入线程模式: CONTROL ...
- 基础数据类型-set
Set是无序不重复元素的序列,基本功能是删除重复元素和测试成员关系, 创建一个集合可以用set()或者({}),但是创建一个空集合只能用set(): s1 = set() print("s1 ...
- hustoj题目标准xml格式
具体格式可见google code. 分析了一下发现像<time_limit></time_limit><memory_limit></memory_limi ...
- leetcode 整理
1.Two Sum 构造Comparator,KSum 这一类的问题最基本的一题, 解法: 先sort,然后双指针,头尾各一个.进行加逼找值. 对于其余的KSum最终是降次到2次. 如3Sum固定一个 ...