DP————最小覆盖问题
原题:https://www.luogu.org/problem/P2279
题解转载自:https://www.luogu.org/blog/contributation/solution-p2279
思路
找最低没被覆盖到的点,并在它的祖父处设一个消防站。考虑到这个点的所有子孙后代都已经被覆盖了,因此这时覆盖祖父能盖到更多额外的点,并保证结果不会更差。
很多思路是用dfs或堆求取最低节点,实际上没必要,只要预处理出深度(边输入边处理)并排序,碰到已覆盖就跳过,未覆盖就在祖父处设消防站,ans++。
问题在于怎样才能判断这个点覆盖到了没有。对于儿子或孙子覆盖他,可以在在儿子处设站时就标记它;而对于父亲和祖父覆盖他,可以用儿子对父亲的映射f来解决;问题在于兄弟。其实,可以用o数组维护“离i最近的消防站到i的距离”,当o[父亲]==1时,就能确定它是否被覆盖。
代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#define N 2020
#define FOR(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
int n,b[N],f[N],d[N],o[N],ans,u,v,w;
bool cmp(int x,int y){return d[x]>d[y];}
int main(){
scanf("%d",&n);b[1]=1,o[1]=o[0]=N;
FOR(i,2,n) scanf("%d",&f[i]),d[i]=d[f[i]]+1,b[i]=i,o[i]=N;
sort(b+1,b+n+1,cmp);
FOR(i,1,n){
v=b[i],w=f[v],u=f[f[v]];
o[v]=min(o[v],min(o[w]+1,o[u]+2));
if(o[v]>2){
o[u]=0,ans++;
o[f[u]]=min(o[f[u]],1),o[f[f[u]]]=min(o[f[f[u]]],2);
}
}printf("%d",ans);
}
这种方法的普适性很强,可以解决半径为k的最小覆盖问题。而且不用存图。只需要把维护“父亲和爷爷”改成维护“上位k位祖先”即可,复杂度O(N*K),常数也很小。
DP————最小覆盖问题的更多相关文章
- poj 1463树形dp 树的最小覆盖
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #i ...
- Contest20140705 testC DP
testC 输入文件: testC.in 输出文件testC.out 时限1000ms 问题描述: ,⋯,an. ,a2,a3,⋯,an) ,⋯,alm. ,al2,al3,⋯,alm) 现要求G=g ...
- 最小覆盖_KEY
最小覆盖(cover)..线段树 [题目描述] 给定 N 个区间[Li,Ri],需要你按照顺序选出一个区间序列使得[1,M]完全被覆盖.并且在选出来的序列中,某个区间[a,b]之前必须保证[1,a]都 ...
- 动态dp初探
动态dp初探 动态区间最大子段和问题 给出长度为\(n\)的序列和\(m\)次操作,每次修改一个元素的值或查询区间的最大字段和(SP1714 GSS3). 设\(f[i]\)为以下标\(i\)结尾的最 ...
- 【POJ3171】Cleaning Shifts 带权区间最小覆盖
题目大意:给定一个长度为 N 的序列,求带权区间最小覆盖. 题解:设 \(dp[i]\) 表示从左端点到 i 的最小权值是多少,则状态转移为:\(dp[e[i].ed]=min\{dp[j],j\in ...
- DP重开
颓了差不多一周后,决定重开DP 这一周,怎么说,学了学trie树,学了学二叉堆,又学了学树状数组,差不多就这样,然后和cdc一番交流后发现,学这么多有用吗?noip的范围不就是提高篇向外扩展一下,现在 ...
- POJ 2836 Rectangular Covering(状压DP)
[题目链接] http://poj.org/problem?id=2836 [题目大意] 给出二维平面的一些点,现在用一些非零矩阵把它们都包起来, 要求这些矩阵的面积和最小,求这个面积和 [题解] 我 ...
- CSU-1531 Jewelry Exhibition —— 二分图匹配(最小覆盖点)
题目链接:https://vjudge.net/problem/CSU-1531 Input Output Sample Input 2 1 5 3 0.2 1.5 0.3 4.8 0.4 3.5 4 ...
- 洛谷 P2279 [HNOI2003]消防局的设立 (树形dp or 贪心)
一看到这道题就知道是树形dp 之前做过类似的题,只不过保护的范围是1 所以简单很多. 这道题保护的范围是2,就复杂了很多. 我就开始列状态,然后发现竟然有5种 然后我就开始列方程. 但是我考虑的时候是 ...
随机推荐
- flutter 跳转至根路由
上代码 //flutter 登录后跳转到根路由 Navigator.of(context).pushAndRemoveUntil( new MaterialPageRoute(builder: (co ...
- JavaScript 运算符的优先级
㈠逗号(,)运算符 ⑴使用 , 可以分割多个语句,一般可以在声明多个变量时使用 , : ⑵使用 , 运算符同时声明多个变量 // var a , b , c ; ⑶可以同时声明多个变量并赋值 ...
- TabSheet源码
TabSheet.h #if !defined(AFX_TABSHEET_H__42EE262D_D15F_46D5_8F26_28FD049E99F4__INCLUDED_) #define AFX ...
- IAT表和导入表
1.关于IAT(import address table)表 当exe程序中调用dll中的函数时,反汇编可以看到,call后面并不是跟的实际函数的地址,而是给了一个地址:
- Luogu P2146 [NOI2015]软件包管理器 树剖
卸载:把子树清空: 安装:把自己到$1$的链改为$1$ #include<cstdio> #include<iostream> #include<cstring> ...
- Sysinternals
http://baike.baidu.com/link?url=LwEFVIcB4h8WaS6sVVH2toBJ0GZUA28yymm1sLsGpDrzF3G2BCZenlHwIsYZdVJZQExE ...
- [Luogu] 逛公园
https://www.luogu.org/problemnew/show/P3953 https://www.zybuluo.com/wsndy-xx/note/1134388 #include&l ...
- 近期将要学习的内容(flag)
块状链表 左偏树 最大流,最小割 费用流 数位DP 计算几何 主席树 树套树(弃疗) 斜率优化 manacher kmp,exkmp 树链剖分 splay树(只看了理论) Trie树 线段树操作及应用 ...
- vue-cli3项目首页加载速度优化(cdn加速,路由懒加载,gzip压缩)
今天打算上线vue的单页面项目,上线后,首页加载速度巨慢! 原因是项目上线后,网速不够快,加载js,css等资源很慢, 打开打包好的文件发现chunk-vendors.xxxxxxx.js的包很大,达 ...
- 1.4 JAVA日期处理
一.JAVA日期 参考链接:https://www.runoob.com/java/java-date-time.html 1.日期两个构造函数 1.第一个构造函数使用当前日期和时间来初始化对象.Da ...