洛谷P2458 保安站岗
传送门啦
分析:
树形dp刚刚入门,这是我做的第一个一个点同时受父亲节点和儿子节点控制的题目。
由于这个题中某一个点放不放保安与父亲和儿子都有关系(因为线段的两个端点嘛),所以我们做题时就要考虑全面。
假设dp数组为f[i][j]:其中f[i][0]表示选择自己(本身这个点),f[i][1]表示自己不选,儿子选(不选本身这个点,而选择这个点的儿子节点),f[i][2]表示自己不选,父亲选(不选本身这个点而选择这个点的父亲节点)
有点啰嗦。。。
看了我的dp数组大家可能有疑问了,树形dp不是用儿子去更新父亲吗?dp不是没有后效性吗?为什么这个点可以看他的父亲?..其实我也是从别人嘴中知道有一种叫做未来计算的东西,就是可以把事先没有发生的但是肯定可以发生的费用加到答案中。
dp转移方程:
设x的儿子节点是v
f[x][0] += min(f[v][1] , min(f[v][2] , f[v][0]))
f[x][2] += min(f[v][0] , f[v][1])
注意:
f[x][1]如果有很多儿子怎么办?
当然,自己不选也不一定所有的儿子都选,我们只需要选择一个最优的儿子,我们其实可以记录一个f[v][0] - f[v][1]的最小值,最后加进去就好了.
if(f[v][] <= f[v][]){
f[x][] += f[v][];
yes = true;
}
else {
f[x][] += f[v][];
minn = min(minn , f[v][] - f[v][]);
}
代码的话就是这样的。yesyes就是打另一个标记,具体怎么用,看总代码吧,就不赘述了。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = ; inline int read(){
char ch = getchar();
int f = , x = ;
while(ch > '' || ch < ''){if(ch == '-')f = -;ch = getchar();}
while(ch >= '' && ch <= ''){x = (x << ) + (x << ) + ch - '';ch = getchar();}
return x * f;
} int n,flag,k,m,r;
int f[maxn][],son[maxn];
//f[i][0]:自己选 ,f[i][1]:自己不选,儿子选 ,f[i][2]:自己不选,父亲选
int head[maxn],tot; struct Edge{
int from,to,next;
}edge[maxn << ]; void add(int u,int v){
edge[++tot].from = u;
edge[tot].to = v;
edge[tot].next = head[u];
head[u] = tot;
} void dfs(int x,int fa){
f[x][] = son[x];
for(int i=head[x];i;i=edge[i].next){
int v = edge[i].to;
if(v != fa) dfs(v , x);
}
bool yes = false , have = false;
int minn = 1e9 ;
for(int i=head[x];i;i=edge[i].next){
int v = edge[i].to;
have = true;
f[x][] += min(f[v][] , min(f[v][] , f[v][]));
f[x][] += min(f[v][] , f[v][]);
if(f[v][] <= f[v][]){
f[x][] += f[v][];
yes = true;
}
else {
f[x][] += f[v][];
minn = min(minn , f[v][] - f[v][]);
}
}
if(!yes) f[x][] += minn;
if(!have) f[x][] = 1e9;
} int main(){
n = read();
for(int i=;i<=n;i++){
flag = read(); k = read();
m = read();
son[flag] = k;
if(m != ){
for(int j=;j<=m;j++){
r = read();
add(flag , r); add(r , flag);
}
}
}
memset(f , , sizeof(f));
dfs( , );
printf("%d\n",min(f[][] , f[][]));
return ;
}
洛谷P2458 保安站岗的更多相关文章
- C++ 洛谷 P2458 [SDOI2006]保安站岗 from_树形DP
P2458 [SDOI2006]保安站岗 没学树形DP的,看一下. 题目大意:一棵树有N个节点,现在需要将所有节点都看守住,如果我们选择了节点i,那么节点i本身,节点i的父亲和儿子都会被看守住. 每个 ...
- 洛谷 P2458 [SDOI2006]保安站岗
题目传送门 解题思路: 树形DP 可知一个点被控制有且仅有一下三种情况: 1.被父亲节点上的保安控制 2.被儿子节点上的保安控制 3.被当前节点上的保安控制 我们设dp[0/1/2][u]表示u节点所 ...
- 【题解】保安站岗[P2458]皇宫看守[LOJ10157][SDOI2006]
[题解]保安站岗[P2458]皇宫看守[LOJ10157][SDOI2006] 传送门:皇宫看守\([LOJ10157]\) 保安站岗 \([P2458]\) \([SDOI2006]\) [题目描述 ...
- Luogu P2458 [SDOI2006]保安站岗(树形dp)
P2458 [SDOI2006]保安站岗 题意 题目描述 五一来临,某地下超市为了便于疏通和指挥密集的人员和车辆,以免造成超市内的混乱和拥挤,准备临时从外单位调用部分保安来维持交通秩序. 已知整个地下 ...
- 洛谷1640 bzoj1854游戏 匈牙利就是又短又快
bzoj炸了,靠离线版题目做了两道(过过样例什么的还是轻松的)但是交不了,正巧洛谷有个"大牛分站",就转回洛谷做题了 水题先行,一道傻逼匈牙利 其实本来的思路是搜索然后发现写出来类 ...
- 洛谷P1352 codevs1380 没有上司的舞会——S.B.S.
没有上司的舞会 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description Ural大学有N个职员,编号为1~N.他们有 ...
- 洛谷P1108 低价购买[DP | LIS方案数]
题目描述 “低价购买”这条建议是在奶牛股票市场取得成功的一半规则.要想被认为是伟大的投资者,你必须遵循以下的问题建议:“低价购买:再低价购买”.每次你购买一支股票,你必须用低于你上次购买它的价格购买它 ...
- 洛谷 P2701 [USACO5.3]巨大的牛棚Big Barn Label:二维数组前缀和 你够了 这次我用DP
题目背景 (USACO 5.3.4) 题目描述 农夫约翰想要在他的正方形农场上建造一座正方形大牛棚.他讨厌在他的农场中砍树,想找一个能够让他在空旷无树的地方修建牛棚的地方.我们假定,他的农场划分成 N ...
- 洛谷P1710 地铁涨价
P1710 地铁涨价 51通过 339提交 题目提供者洛谷OnlineJudge 标签O2优化云端评测2 难度提高+/省选- 提交 讨论 题解 最新讨论 求教:为什么只有40分 数组大小一定要开够 ...
随机推荐
- %1$s %1$d Android string (java & Android 格式化字符串)
1$s // String%1$d // int //R.string.old:<string name="old">我今年%1$d岁了</string> ...
- 团体程序设计天梯赛 L2-028. 秀恩爱分得快
1.输入-0(第一部分.第二部分),输出-02.只统计与两个人的亲密程度,否则超时 Data: 4 14 -0 1 -2 3-0 1 -0 1 ------ 4 1 3 1 -2 3-0 1 -0 1 ...
- Kubernetes之利用prometheus监控K8S集群
prometheus它是一个主动拉取的数据库,在K8S中应该展示图形的grafana数据实例化要保存下来,使用分布式文件系统加动态PV,但是在本测试环境中使用本地磁盘,安装采集数据的agent使用Da ...
- python文件加入python环境变量
在python中,把一个python文件加入到python环境变量中,以方便其他python文件调用. 方式一: import sys sys.path.append(r'E:\syz\ly-code ...
- js加载超时 nginx静态资源
server { listen ; server_name www.example.com; client_max_body_size 20M; root /xxx/xxx;//项目路径 locati ...
- Nlog写日志到数据库
https://github.com/nlog/NLog/wiki/Database-Target
- [USACO09NOV]硬币的游戏A Coin Game
https://daniu.luogu.org/problemnew/show/P2964 dp[i][j] 表示桌面上还剩i枚硬币时,上一次取走了j个的最大得分 枚举这一次要拿k个,转移到dp[i- ...
- codevs 1080 线段树练习 CDQ分治
codevs 1080 线段树练习 http://codevs.cn/problem/1080/ 时间限制: 1 s 空间限制: 128000 KB 题目描述 Description 一行N个 ...
- How to Tell Science Stories with Maps
Reported Features How to Tell Science Stories with Maps August 25, 2015 Greg Miller This map, part ...
- 织梦dedecms 模板文件不存在,无法解析文档!
方法一:[此对应喜欢把模板文件使用".html"的格式,] /include/arc.archives.class.php 556行 if (!preg_match("# ...