C++ 洛谷 P2458 [SDOI2006]保安站岗 from_树形DP
P2458 [SDOI2006]保安站岗
题目大意:一棵树有N个节点,现在需要将所有节点都看守住,如果我们选择了节点i,那么节点i本身,节点i的父亲和儿子都会被看守住。
每个节点有一个选择代价,求完成任务所需要的最小的代价。
分析:根据每个节点其实有只有三个状态:
①被自己看守;②被儿子看守;③被父亲看守。
我们设这三种状态分别为F1,F2,F3。
当然最终作为答案的根节点没有父亲就没有F3。
接下来我们要考虑怎么转移。
首先看F1,我们规定F1[ i ]代表的是i节点被自己看守且以i为根的子树都已被看守的最小代价,也就是说一定会选择 i 节点自己,答案中必定会加入选择他自己的代价Wi。
因为这个点会被自己看管,所以只要考虑在其儿子的三个状态中选一个最小的,保证这个节点下面的子树都已被看守就行了。
所以F1[ i ] += min( F1[ Si ], F2[ Si ], F3[ Si ] ) + w[ i ],其中Si代表i节点的儿子。
接下来看F2,我们规定F2[ i ]代表i节点被儿子看守且以i为根的子树都已被看守的最小代价,也就是说一定不选i节点,但是至少要在i节点的儿子中选择一个而且最多也就选一个,因为代
价是正数,选一个就能把i看住,就不需要选择多余的点在增加代价了。
因为i节点不能被选,所以只能在其儿子的F1, F2状态中选择小的(F3[ Si ]代表选择i节点,而不能选i节点,所以不能用F3[ Si ]),来保证其子树都已被看守。
所以F2[ i ] += min{ F1[ Si ], F2[ Si ] } + t。t代表选择一个儿子的最小代价:t = F1[ Si ] - min{ F1[ Si ], F2[ Si ] }。
顺便解释一下t的转移:t是Si被看管的代价中选一个最小的,如果是F1,那么说明Si已经被选,就不用再加W[ Si ]了,如果是F2,那么F1 - F2 = W[ i ]。(注意F1和F2代表的意义)
最后看F3,我们规定F3[ i ]代表i节点被父亲看守且以i为根的子树都已经被看守的最小代价,也就是说一定不选i节点和其儿子节点,必须选择他的父亲。因为必须选择父亲,那么i一定会被父亲看守,那么我们只要保证其下面的子树都已被看守,就是在儿子的F1, F2中选一个小的,因为还是不能选i,所以其儿子的F3状态仍然不用考虑,同F2。
所以F3[ i ] += min{ F1[ Si ], F2[ Si ]}。
看代码吧……………*&%^qaq^%&*
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int maxn=;
const int inf=0x3f3f3f3f;
int n;
struct edge{
int num,k,m;
}e[maxn];
int s[maxn][maxn],fa[maxn],f1[maxn],f2[maxn],f3[maxn];
int ans;
void tree_dp(int i)
{
f1[i]=e[i].k;
f2[i]=f3[i]=;
int minn=inf;
for (int j=;j<=e[i].m;j++)
{
tree_dp(s[i][j]);
f1[i]+=min(f1[s[i][j]],min(f2[s[i][j]],f3[s[i][j]]));
f2[i]+=min(f1[s[i][j]],f2[s[i][j]]);
int t=f1[s[i][j]]-min(f1[s[i][j]],f2[s[i][j]]);
minn=min(minn,t);
f3[i]+=min(f1[s[i][j]],f2[s[i][j]]);
}
f2[i]+=minn;
}
void work()
{
scanf("%d",&n);
for(int i=;i<=n;i++)
{
scanf("%d",&e[i].num); //注意读入
scanf("%d%d",&e[e[i].num].k,&e[e[i].num].m);
for (int j=;j<=e[e[i].num].m;j++)
{
scanf("%d",&s[e[i].num][j]); //儿子节点数
fa[s[e[i].num][j]]=e[i].num;
}
}
memset(f1,inf,sizeof(f1));
memset(f2,inf,sizeof(f2));
memset(f3,inf,sizeof(f3));
for (int i=;i<=n;i++)
{
if(!fa[i]) //没有父亲,就是根节点
{
tree_dp(i);
ans=min(f1[i],f2[i]); //根节点只有2种情况
break;
}
}
printf("%d",ans);
}
int main()
{
work();
return ;
}
C++ 洛谷 P2458 [SDOI2006]保安站岗 from_树形DP的更多相关文章
- 洛谷 P2458 [SDOI2006]保安站岗
题目传送门 解题思路: 树形DP 可知一个点被控制有且仅有一下三种情况: 1.被父亲节点上的保安控制 2.被儿子节点上的保安控制 3.被当前节点上的保安控制 我们设dp[0/1/2][u]表示u节点所 ...
- Luogu P2458 [SDOI2006]保安站岗【树形Dp】
题目描述 五一来临,某地下超市为了便于疏通和指挥密集的人员和车辆,以免造成超市内的混乱和拥挤,准备临时从外单位调用部分保安来维持交通秩序. 已知整个地下超市的所有通道呈一棵树的形状:某些通道之间可以互 ...
- Luogu P2458 [SDOI2006]保安站岗(树形dp)
P2458 [SDOI2006]保安站岗 题意 题目描述 五一来临,某地下超市为了便于疏通和指挥密集的人员和车辆,以免造成超市内的混乱和拥挤,准备临时从外单位调用部分保安来维持交通秩序. 已知整个地下 ...
- 洛谷 P2015 二叉苹果树(codevs5565) 树形dp入门
dp这一方面的题我都不是很会,所以来练(xue)习(xi),大概把这题弄懂了. 树形dp就是在原本线性上dp改成了在 '树' 这个数据结构上dp. 一般来说,树形dp利用dfs在回溯时进行更新,使用儿 ...
- 洛谷 P3267 - [JLOI2016/SHOI2016]侦察守卫(树形 dp)
洛谷题面传送门 经典题一道,下次就称这种"覆盖距离不超过 xxx 的树形 dp"为<侦察守卫模型> 我们考虑树形 \(dp\),设 \(f_{x,j}\) 表示钦定了 ...
- 洛谷 P7163 - [COCI2020-2021#2] Svjetlo(树形 dp)
洛谷题面传送门 神仙级别的树形 dp. u1s1 这种代码很短但巨难理解的题简直是我的梦魇 首先这种题目一看就非常可以 DP 的样子,但直接一维状态的 DP 显然无法表示所有情况.注意到对于这类统计一 ...
- 洛谷【P2458】[SDOI2006]保安站岗 题解 树上DP
题目描述 五一来临,某地下超市为了便于疏通和指挥密集的人员和车辆,以免造成超市内的混乱和拥挤,准备临时从外单位调用部分保安来维持交通秩序. 已知整个地下超市的所有通道呈一棵树的形状:某些通道之间可以互 ...
- P2458 [SDOI2006]保安站岗[树形dp]
题目描述 五一来临,某地下超市为了便于疏通和指挥密集的人员和车辆,以免造成超市内的混乱和拥挤,准备临时从外单位调用部分保安来维持交通秩序. 已知整个地下超市的所有通道呈一棵树的形状:某些通道之间可以互 ...
- [Luogu][P2458] [SDOI2006]保安站岗
题目链接 看起来似乎跟最小点覆盖有点像.但区别在于: 最小点覆盖要求所有边在其中,而本题要求所有点在其中. 即:一个点不选时,它的儿子不一定需要全选. 画图理解: 对于这样一幅图,本题中可以这样选择: ...
随机推荐
- Qt5官方demo分析集10——Qt Quick Particles Examples - Emitters
此系列的所有文章都可以在这里查看http://blog.csdn.net/cloud_castle/article/category/2123873 前段时间去听了Qt在北京的开发人员大会,感觉QML ...
- textblock的LineHeight的调整
原文:textblock的LineHeight的调整 <TextBlock Width="113.594" Height="73.667" Text=&q ...
- 芒果TV For Windows10 成长历史 & 迭代历史 & 新闻报道
芒果TV 是国内领先的基于Windows10操作系统并支持Windows10全系列设备的视频应用和内容服务商. Win10商店版<芒果TV>是湖南快乐阳光互动娱乐传媒有限公司专门为Wind ...
- Qt 5.9对Mac的图形显示有许多改进
We have some platform specific improvements as well as support for new platforms and compilers comin ...
- GRPC 1.3.4 发布,Google 高性能 RPC 框架(Java C++ Go)
GRPC 1.3.4 发布了,GRPC 是一个高性能.开源.通用的 RPC 框架,面向移动和 HTTP/2 设计,是由谷歌发布的首款基于 Protocol Buffers 的 RPC 框架. GRPC ...
- 微信小程序把玩(三十四)Audio API
原文:微信小程序把玩(三十四)Audio API 没啥可值得太注意的地方 重要属性: 1. wx.getBackgroundAudioPlayerState(object) 获取播放状态 2.wx.p ...
- WPF用DirectSound播放声音
示例代码: var fileName = @"D:\WindowsLogon.wav"; DevicesCollection sound_devices = new Devices ...
- Android零基础入门第61节:滚动视图ScrollView
原文:Android零基础入门第61节:滚动视图ScrollView 前面几期学习了ProgressBar系列组件.ViewAnimator系列组件.Picker系列组件和时间日期系列组件,接下来几期 ...
- linux输出信息调试信息重定向
最近在做一个android系统移植的项目,所使用的开发板com1是调试串口,就是说会有uboot和kernel的调试信息打印在com1上(ttySAC0).因为后期要使用ttySAC0作为上层应用通信 ...
- 中芯国际在CSTIC上悉数追赶国际先进水平的布局
作为中国最大.工艺最先进的晶圆厂,中芯国际的一举一动都会受到大家的关注.在由SEMI主办的2017’中国国际半导体技术大会(CSTIC 2017)上,中芯国际CEO邱慈云博士给我们带来了最新的介绍. ...