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]保安站岗
题目链接 看起来似乎跟最小点覆盖有点像.但区别在于: 最小点覆盖要求所有边在其中,而本题要求所有点在其中. 即:一个点不选时,它的儿子不一定需要全选. 画图理解: 对于这样一幅图,本题中可以这样选择: ...
随机推荐
- Webx框架:Pipeline基本介绍
Pipeline. 它是管道的含义.一个管道阀门可以安装非常多.有许多可能的分支.它是用来控制页处理.它需要在被定义pipeline.xml文件.该文件是为每个阀的标签.该文件可以放一些简单的控制语句 ...
- 形态学-扩大-C代码
直接在代码,难.他们明白: void MorhpolotyDilate_ChenLee(unsigned char* pBinImg, int imgW, int imgH, Tpoint* mask ...
- 用MVVM模式开发中遇到的零散问题总结(5)——将动态加载的可视元素保存为图片的控件,Binding刷新的时机
原文:用MVVM模式开发中遇到的零散问题总结(5)--将动态加载的可视元素保存为图片的控件,Binding刷新的时机 在项目开发中经常会遇到这样一种情况,就是需要将用户填写的信息排版到一张表单中,供打 ...
- Android 9.0 Dialog不显示
Tester报了一个bug,大概如下: 页面:Activity1 dialog1(半透明遮罩样式) Activity2 dialog2 场景:Activity1弹出dialog1,dialog1弹出a ...
- WPF 窗体边框处理
一般做wpf窗口时都不会使用默认的标题栏等,会把他隐藏掉 此时设置以下属性 WindowStyle.AllowsTransparency.ResizeMode 中的两个或三个都能达到目的. 有一种场景 ...
- 基于X.509证书和SSL协议的身份认证过程实现(OpenSSL可以自己产生证书,有TCP通过SSL进行实际安全通讯的实际编程代码)good
上周帮一个童鞋做一个数字认证的实验,要求是编程实现一个基于X.509证书认证的过程,唉!可怜我那点薄弱的计算机网络安全的知识啊!只得恶补一下了. 首先来看看什么是X.509.所谓X.509其实是一种非 ...
- UWP开发:获取用户当前所在的网络环境(WiFi、移动网络、LAN…)
原文:UWP开发:获取用户当前所在的网络环境(WiFi.移动网络.LAN-) UWP开发:获取用户当前所在的网络环境: 在uwp开发中,有时候,我们需要判断用户所在的网络,是WiFi,还是移动网络,给 ...
- 程序员该如何过好他的整个职业生涯?(最重要的是你得一直往前走。拐点不是你的工资。想起很久前有个人说我“逻辑性”比较强)good
作者|池建强 编辑|小智 戳阅读原文,获得短信提醒,不错过下次InfoQ大咖说直播! 1 写在前面 加入极客邦的第一天就被拉到了「大咖说」的现场,这也是我始料未及的事情.从锤子科技正式离职之后,我 ...
- 使用Nodejs实现实时推送MySQL数据库最新信息到客户端
下面我们要做的就是把MySQL这边一张表数据的更新实时的推送到客户端,比如MySQL这边表的数据abc变成123了,那使用程序就会把最新的123推送到每一个连接到服务器的客户端.如果服务器的连接的客户 ...
- flask(二)
1.装饰器坑 使用装饰器后,视图函数名字相同问题view function错误问题 1.给装饰器加functiontools 2.反向生成url地址标志,指定endpoint(endpoint必须唯一 ...