[ SDOI 2006 ] 保安站岗
\(\\\)
Description
给出一棵 \(n\) 个节点以 \(1\) 为根的树,一个节点的覆盖半径是 \(1\) ,点有点权 \(val_x\) 。
选择一些点,使得点权和最小,同时每个节点要么被选择要么被周围的点覆盖。
- \(n\le 1500,0\le val_x\le 10^4\)
\(\\\)
Solution
树形DP 的讨论。
注意到覆盖有可能呈现出两层都没有选点的情况 (下面被子树覆盖,上面被父节点覆盖),所以状态设计要注意。
设\(f[i][0/1/2]\),表示节点 \(i\) 及其子树的覆盖代价,明确定义:
- \(0\) 表示选择自己,覆盖整个子树的最小代价
- \(1\) 表示第 \(i\) 个节点被自己的子树的根节点覆盖,不选择自己的最小代价
- \(2\) 表示第 \(i\) 个节点被父节点覆盖,此时当前节点的所有子树都已经完成覆盖的最小代价
转移讨论起来就很方便了。
\(0\) :显然要选自己,所以所有子树选什么都合法,对每个子树累加 \(min(f[v][0],f[v][1],f[v][2])\) 。
\(2\):不选自己,子树内部显然不能再向当前点提出需求,所以对子树累加 \(min(f[v][0],f[v][1])\) 。
\(1\) 的转移有点意思。
如果我们贪心的选,选择 \(0\) 状态最小的子树,剩下的子树都选 \(1\) 状态,不一定是最优的。
因为这个 \(0\) 状态最小的子树,他的 \(1\) 状态可能会更小的多,这个差值完全能够允许另一个 \(1\) 状态变成 \(0\) 状态。
\(\\\)
所以考虑替换, \(yy\) 出来一个比较好的写法。
先对所有子树求出 \(sum=min(f[v][0],f[v][1])\) 。
同时维护 \(tmp=min(\ f[v][0]-\min(f[v][0],f[v][1])\ )\)。
\(\\\)
这个 \(sum\) 的含义是,不考虑子树覆盖当前节点, 子树内部覆盖的最小值,可以发现其实就是 \(f[u][2]\) 。
\(tmp\) 的含义就是,把这个 \(sum\) 集合里的任意一个点不管之前选的什么,现在变成 \(0\) 状态的最小代价。
如果之前求 \(sum\) 的时候选了一个 \(0\) 状态,那么这个 \(tmp\) 显然是 \(0\) 。
如果之前没有选到任意一个 \(0\) 状态,那么这个 \(tmp\) 就是所有的 \(1\) 状态里,变成 \(0\) 状态的最小代价。
所以有 \(f[v][1]=f[v][2]+tmp\) 。
\(\\\)
Code
#include<cmath>
#include<cstdio>
#include<cctype>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define N 1510
#define gc getchar
#define R register
#define inf 2000000000
using namespace std;
inline int rd(){
int x=0; bool f=0; char c=gc();
while(!isdigit(c)){if(c=='-')f=1;c=gc();}
while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=gc();}
return f?-x:x;
}
int n,m,tot,hd[N],f[N][3],val[N];
struct edge{int to,nxt;}e[N<<1];
inline void add(int u,int v){
e[++tot].to=v; e[tot].nxt=hd[u]; hd[u]=tot;
}
//0: 选自己
//1: 选子树内覆盖自己
//2:选父节点覆盖自己
void dfs(int u,int fa){
int mn=inf;
f[u][0]=val[u]; f[u][2]=0;
for(R int i=hd[u],v;i;i=e[i].nxt)
if((v=e[i].to)!=fa){
dfs(v,u);
f[u][0]+=min(f[v][2],min(f[v][1],f[v][0]));
f[u][2]+=min(f[v][1],f[v][0]);
mn=min(mn,f[v][0]-min(f[v][1],f[v][0]));
}
f[u][1]=f[u][2]+mn;
}
int main(){
n=rd();
memset(f,0x3f,sizeof(f));
for(R int i=1,u,cnt;i<=n;++i){
u=rd(); val[u]=rd(); cnt=rd();
for(R int j=1,v;j<=cnt;++j){v=rd();add(u,v);add(v,u);}
}
dfs(1,0);
printf("%d\n",min(f[1][0],f[1][1]));
return 0;
}
[ SDOI 2006 ] 保安站岗的更多相关文章
- 【Luogu2458】保安站岗(动态规划)
[Luogu2458]保安站岗(动态规划) 题面 题目描述 五一来临,某地下超市为了便于疏通和指挥密集的人员和车辆,以免造成超市内的混乱和拥挤,准备临时从外单位调用部分保安来维持交通秩序. 已知整个地 ...
- C++ 洛谷 P2458 [SDOI2006]保安站岗 from_树形DP
P2458 [SDOI2006]保安站岗 没学树形DP的,看一下. 题目大意:一棵树有N个节点,现在需要将所有节点都看守住,如果我们选择了节点i,那么节点i本身,节点i的父亲和儿子都会被看守住. 每个 ...
- 【题解】保安站岗[P2458]皇宫看守[LOJ10157][SDOI2006]
[题解]保安站岗[P2458]皇宫看守[LOJ10157][SDOI2006] 传送门:皇宫看守\([LOJ10157]\) 保安站岗 \([P2458]\) \([SDOI2006]\) [题目描述 ...
- Luogu P2458 [SDOI2006]保安站岗(树形dp)
P2458 [SDOI2006]保安站岗 题意 题目描述 五一来临,某地下超市为了便于疏通和指挥密集的人员和车辆,以免造成超市内的混乱和拥挤,准备临时从外单位调用部分保安来维持交通秩序. 已知整个地下 ...
- 洛谷【P2458】[SDOI2006]保安站岗 题解 树上DP
题目描述 五一来临,某地下超市为了便于疏通和指挥密集的人员和车辆,以免造成超市内的混乱和拥挤,准备临时从外单位调用部分保安来维持交通秩序. 已知整个地下超市的所有通道呈一棵树的形状:某些通道之间可以互 ...
- [luogu 2458][SDOI2006]保安站岗
题目描述 五一来临,某地下超市为了便于疏通和指挥密集的人员和车辆,以免造成超市内的混乱和拥挤,准备临时从外单位调用部分保安来维持交通秩序. 已知整个地下超市的所有通道呈一棵树的形状:某些通道之间可以互 ...
- 洛谷P2458 保安站岗
传送门啦 分析: 树形dp刚刚入门,这是我做的第一个一个点同时受父亲节点和儿子节点控制的题目. 由于这个题中某一个点放不放保安与父亲和儿子都有关系(因为线段的两个端点嘛),所以我们做题时就要考虑全面. ...
- Luogu P2458 [SDOI2006]保安站岗【树形Dp】
题目描述 五一来临,某地下超市为了便于疏通和指挥密集的人员和车辆,以免造成超市内的混乱和拥挤,准备临时从外单位调用部分保安来维持交通秩序. 已知整个地下超市的所有通道呈一棵树的形状:某些通道之间可以互 ...
- [Luogu2458][SDOI2006]保安站岗
题目描述 五一来临,某地下超市为了便于疏通和指挥密集的人员和车辆,以免造成超市内的混乱和拥挤,准备临时从外单位调用部分保安来维持交通秩序. 已知整个地下超市的所有通道呈一棵树的形状:某些通道之间可以互 ...
随机推荐
- Django学习系列之路由系统
一.基于App的路由 作用: 根据App对路由规则进行分类,在全局urls.py包含某个项目的urls.py 示例 定义全局urls.py(全局路由系统) #导入include from django ...
- go语言中的timer 和ticker定时任务
https://mmcgrana.github.io/2012/09/go-by-example-timers-and-tickers.html --------------------------- ...
- nodejs连接sqlserver
nodejs连接sqlserver http://blog.csdn.net/kkkkkxiaofei/article/details/31353091
- 从头认识Spring-2.3 注解装配-@autowired(4)-required(2)
这一章节我们来继续具体讨论一下@autowired里面的參数required.在多构造器注入的情况. 1.domain(重点) 蛋糕类: package com.raylee.my_new_sprin ...
- AutoCAD如何编辑块,打散块
选中块之后,点击最右侧的最后一个工具"分解"即可.
- Android插屏动画效果
公司研发SDK,须要类似有米插屏的动画效果,研究了下,写了一个DEMO,凝视非常具体了. <span style="font-size:24px;">package c ...
- MongoDb 学习教程
MongoDB教程首页 MongoDB 介绍 MongoDB 优点 MongoDB 安装(Window/Linux) MongoDB 数据模型 MongoDB 创建数据库 MongoDB 删除数据库 ...
- 工作总结 default Console.WriteLine(default(Guid));
泛型代码中的默认关键字 在泛型类和泛型方法中产生的一个问题是,在预先未知以下情况时,如何将默认值分配给参数化类型 T: T 是引用类型还是值类型. 如果 T 为值类型,则它是数值还是结构. 给定参数化 ...
- HDU 1231——最大连续子序列(DP)
最大连续子序列 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Su ...
- Cacti监控Redis实现过程
Cacti是一套基于PHP,MySQL,SNMP及RRDTool开发的网络流量监測图形分析工具.被广泛的用于对server的运维监控中,Cacti提供了一种插件式的管理.仅仅要按要求写好特定的模板,那 ...