题目传送门

解题思路:

树形DP

可知一个点被控制有且仅有一下三种情况:

1、被父亲节点上的保安控制

2、被儿子节点上的保安控制

3、被当前节点上的保安控制

我们设dp[0/1/2][u]表示u节点所在子树中全部被控制的最小代价,0表示只有u节点尚未被控制(等待被其父亲节点控制);

1表示u节点已经被控制,但u节点上没有保安,所以不能去控制其父亲节点;2表示u节点上有保安

(机房的神犇说多维数组要把小的那一维写在前面,因为可以优化常数,原理请自行翻阅一本通)

转移:(以下设v是u的儿子节点)

dp[0][u]=∑min(dp[1][v],dp[2][v]) i节点上反正没有保安,那么儿子节点只要保证全部控制即可,显然1,2状态都是满足的

dp[1][u]=∑min(dp[1][v],dp[2][v]) + 某一个dp[2][v] 也就是说对于其中一个儿子取dp[2][v]而其他儿子取min(dp[1][v],dp[2][v])意为i号点必须要找一个儿子来覆盖它,其余随意。这个地方涉及到了算法复杂度的问题,楼下有些题解在这里写的是O(n^2)的转移,但实际上完全可以做到O(n)。具体在代码中细讲。

dp[2][u]=∑min(dp[0][v],dp[1][v],dp[2][v])+val[u] 这个就简单了,i号点上反正有保安了,所有儿子节点都无所谓了,全部可以转移。

AC代码:

 #include<iostream>
#include<cstdio>
#include<vector>
#include<cstring> using namespace std; int n,a[],k,m,f[][];
vector<int> l[]; inline void dfs(int root,int fa) {
bool flag = ;
int sum = ,_min = 0x3f3f3f3f,id = ;
f[root][] = a[root];
f[root][] = f[root][] = ;
for(int i = ;i < l[root].size(); i++) {
if(fa == l[root][i]) continue;
dfs(l[root][i],root);
f[root][] += min(f[l[root][i]][],f[l[root][i]][]);//被父亲保
f[root][] += min(f[l[root][i]][],f[l[root][i]][]);//被儿子保
if(f[l[root][i]][] > f[l[root][i]][]) flag = ;
else _min = min(_min,f[l[root][i]][] - f[l[root][i]][]);
f[root][] += min(f[l[root][i]][],min(f[l[root][i]][],f[l[root][i]][]));//自保
}
if(!flag)
f[root][] += _min;
} int main() {
scanf("%d",&n);
for(int i = ;i <= n; i++) {
scanf("%d%d%d",&k,&a[i],&m);
for(int j = ;j <= m; j++) {
int x;
scanf("%d",&x);
l[k].push_back(x);
l[x].push_back(k);
}
}
memset(f,,sizeof(f));
dfs(,-);
printf("%d",min(f[][],f[][]));
return ;
}

洛谷 P2458 [SDOI2006]保安站岗的更多相关文章

  1. C++ 洛谷 P2458 [SDOI2006]保安站岗 from_树形DP

    P2458 [SDOI2006]保安站岗 没学树形DP的,看一下. 题目大意:一棵树有N个节点,现在需要将所有节点都看守住,如果我们选择了节点i,那么节点i本身,节点i的父亲和儿子都会被看守住. 每个 ...

  2. Luogu P2458 [SDOI2006]保安站岗(树形dp)

    P2458 [SDOI2006]保安站岗 题意 题目描述 五一来临,某地下超市为了便于疏通和指挥密集的人员和车辆,以免造成超市内的混乱和拥挤,准备临时从外单位调用部分保安来维持交通秩序. 已知整个地下 ...

  3. Luogu P2458 [SDOI2006]保安站岗【树形Dp】

    题目描述 五一来临,某地下超市为了便于疏通和指挥密集的人员和车辆,以免造成超市内的混乱和拥挤,准备临时从外单位调用部分保安来维持交通秩序. 已知整个地下超市的所有通道呈一棵树的形状:某些通道之间可以互 ...

  4. P2458 [SDOI2006]保安站岗[树形dp]

    题目描述 五一来临,某地下超市为了便于疏通和指挥密集的人员和车辆,以免造成超市内的混乱和拥挤,准备临时从外单位调用部分保安来维持交通秩序. 已知整个地下超市的所有通道呈一棵树的形状:某些通道之间可以互 ...

  5. [Luogu][P2458] [SDOI2006]保安站岗

    题目链接 看起来似乎跟最小点覆盖有点像.但区别在于: 最小点覆盖要求所有边在其中,而本题要求所有点在其中. 即:一个点不选时,它的儿子不一定需要全选. 画图理解: 对于这样一幅图,本题中可以这样选择: ...

  6. 洛谷【P2458】[SDOI2006]保安站岗 题解 树上DP

    题目描述 五一来临,某地下超市为了便于疏通和指挥密集的人员和车辆,以免造成超市内的混乱和拥挤,准备临时从外单位调用部分保安来维持交通秩序. 已知整个地下超市的所有通道呈一棵树的形状:某些通道之间可以互 ...

  7. 洛谷P2458 保安站岗

    传送门啦 分析: 树形dp刚刚入门,这是我做的第一个一个点同时受父亲节点和儿子节点控制的题目. 由于这个题中某一个点放不放保安与父亲和儿子都有关系(因为线段的两个端点嘛),所以我们做题时就要考虑全面. ...

  8. [luogu 2458][SDOI2006]保安站岗

    题目描述 五一来临,某地下超市为了便于疏通和指挥密集的人员和车辆,以免造成超市内的混乱和拥挤,准备临时从外单位调用部分保安来维持交通秩序. 已知整个地下超市的所有通道呈一棵树的形状:某些通道之间可以互 ...

  9. [Luogu2458][SDOI2006]保安站岗

    题目描述 五一来临,某地下超市为了便于疏通和指挥密集的人员和车辆,以免造成超市内的混乱和拥挤,准备临时从外单位调用部分保安来维持交通秩序. 已知整个地下超市的所有通道呈一棵树的形状:某些通道之间可以互 ...

随机推荐

  1. lunix下的redis安装

    https://blog.csdn.net/qq_35992900/article/details/82950157

  2. 拦截指定数据、修改JS -- mitmproxy

    mitmproxy 配置 mitmproxy源码:https://github.com/mitmproxy/mitmproxy mitmdump -q:屏蔽mitmdump默认的控制台日志,只显示自己 ...

  3. windowsService 程序

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  4. fiddler抓取URL之过滤设置

    Fiddler是强大的抓包工具,它的原理是以web代理服务器的形式进行工作的,使用的代理地址是:127.0.0.1,端口默认为8888,我们也可以通过设置进行修改. 只要是开启了fiddler,我们的 ...

  5. Django创建完全独立的APP

    我们之前已经完成了项目的结构搭建,但是,在Django当中,我们强调的一个重要概念是app,比如Django自带的admin就是一个成功的app典范,那么我们应该如果整理自己的项目结构,才能让我们的a ...

  6. Lua生成比较理想的随机数的方法

    lua需要生成随机数的需求也是很常见的,为了生成看起来更随机的数字,我们需要注意以下几点 我们也需要给随机数设置随机数种子:math.randomseed(xx) lua对随机数种子也是有一定要求的: ...

  7. java 搭积木

    搭积木 小明最近喜欢搭数字积木, 一共有10块积木,每个积木上有一个数字,0~9. 搭积木规则: 每个积木放到其它两个积木的上面,并且一定比下面的两个积木数字小. 最后搭成4层的金字塔形,必须用完所有 ...

  8. P1067 试密码

    P1067 试密码 转跳点:

  9. CentOS 7 搭建本地YUM仓库,并定期同步阿里云源

    目录导航: 1. 系统环境 2. 修改yum 源为阿里云源 3. 安装yum相关的软件 4. 根据源标识同步源到本地目录 5. 安装nginx开启目录权限保证本地机器可以直接本地yum源 6. 客户端 ...

  10. MySQL 批量更新、删除数据shell脚本

    #!/bin/bash. ~/.bash_profilelog=/tmp/update_log_1_$(date +%F).logvstart=1step=100vstop=$((${vstart}+ ...