\(\\\)

\(Description\)


一棵\(N\)个节点的树,树上有\(M\)个节点是关键点,选出\(K\)个特殊点,使得所有关键点到特殊点的距离中最大的最小,输出最大值最小为多少。

  • \(N\in [1,3\times 10^5]\),\(M,K\in [1,N]\)

\(\\\)

\(Solution\)


神仙树形DP验证方式

  • 首先最大值最小一眼二分,关键在于怎么\(check\)这个二分得到的最远距离。
  • 正解树型\(DP\),假设所有子树已经处理完毕,显然可以靠贡献和需求分为四类;
    • \(0\):可向上贡献,子树内已全部覆盖
    • \(1\):可向上贡献,子树内有待覆盖节点
    • \(2\):无可向上覆盖,子树内已全部覆盖
    • \(3\):无可向上覆盖,子树内有待覆盖节点
  • 有趣的是发现\(1\)和\(3\)两类子树根节点的情况可合并,即\(1\)类节点的贡献是无意义的,为什么呢?因为子树内的点无法被覆盖,证明有贡献的点从根节点再往外的贡献长度是小于待覆盖节点到子树根节点距离的。而子树外的点若能够满足覆盖子树内待覆盖节点的要求,则外部节点从当前子树根节点延申出的长度为二倍的二分答案再减掉待覆盖节点到子树根节点的距离,显然比上一个长。于是点分类改为:
    • \(0\):可向上贡献,子树内已全部覆盖
    • \(1\):无可向上覆盖,子树内有待覆盖节点
    • \(2\):无可向上覆盖,子树内已全部覆盖
  • 设\(f[i]\)表示\(i\)号节点:向上最长贡献距离\((1)/\)子树内待覆盖节点到\(i\)号节点最大距离\((2)/0(3)\)。
  • 然后就考虑当前节点的状态。统计所有有贡献的节点在根节点处的最大延申距离,即\(mx_1=max(mx_1,f[i]-1)\);统计所有待覆盖节点到当前根节点处最大距离,即\(mx_2=max(mx_2,f[i]+1)\)。
  • 分情况讨论当前节点状态,注意若子树内待覆盖节点距离等于二分长度,当前点应设为特殊点,同时注意特判\(2\)类节点即可。
  • 还要注意在树型\(DP\)后若\(1\)号节点是待覆盖的使用节点数要\(+1\)。

\(\\\)

\(Code\)


  1. #include<cmath>
  2. #include<cstdio>
  3. #include<cctype>
  4. #include<cstring>
  5. #include<cstdlib>
  6. #include<iostream>
  7. #include<algorithm>
  8. #define N 300010
  9. #define R register
  10. #define gc getchar
  11. using namespace std;
  12. int n,m,tot,cnt,d[N],hd[N];
  13. int f[N],tag[N];
  14. struct edge{int to,nxt;}e[N<<1];
  15. inline void add(int u,int v){
  16. e[++tot].to=v; e[tot].nxt=hd[u]; hd[u]=tot;
  17. }
  18. inline int rd(){
  19. int x=0; bool f=0; char c=gc();
  20. while(!isdigit(c)){if(c=='-')f=1;c=gc();}
  21. while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=gc();}
  22. return f?-x:x;
  23. }
  24. inline void dfs(int u,int fa,int lim){
  25. int mn=-1,mx=d[u]-1;
  26. for(R int i=hd[u];i;i=e[i].nxt)
  27. if(e[i].to!=fa) dfs(e[i].to,u,lim);
  28. for(R int i=hd[u];i;i=e[i].nxt)
  29. if(e[i].to!=fa){
  30. if(tag[e[i].to]==0) mn=max(mn,f[e[i].to]-1);
  31. else if(tag[e[i].to]==1) mx=max(mx,f[e[i].to]+1);
  32. }
  33. if(mn<mx){
  34. if(mx==lim){++cnt; f[u]=lim;tag[u]=0;}
  35. else{f[u]=mx;tag[u]=1;}
  36. }
  37. else if(mn!=-1){f[u]=mn; tag[u]=0;}
  38. else{f[u]=0;tag[u]=2;}
  39. }
  40. inline bool valid(int x){
  41. cnt=0; dfs(1,0,x);
  42. if(tag[1]==1) ++cnt;
  43. return cnt<=m;
  44. }
  45. int main(){
  46. n=rd(); m=rd();
  47. for(R int i=1;i<=n;++i) d[i]=rd();
  48. for(R int i=1,u,v;i<n;++i){
  49. u=rd(); v=rd(); add(u,v); add(v,u);
  50. }
  51. int l=0,r=n;
  52. while(l<r){
  53. int mid=((l+r)>>1);
  54. valid(mid)?r=mid:l=mid+1;
  55. }
  56. printf("%d\n",l);
  57. return 0;
  58. }

[ POI 2011 ] Dynamite的更多相关文章

  1. 解题:POI 2011 Dynamite

    题面 从零开始的DP学习系列之叁 树形DP的基本(常见?)思路:先递归进儿子,然后边回溯边决策,设状态时常设$dp[x]$表示以$x$为根的子树中(具体分析算不算$x$这个点)的情况 显然的二分答案, ...

  2. 解题:POI 2011 Strongbox

    首先洛谷的题面十分的劝退(至少对我这个菜鸡来说是这样),我来解释一下(原来的英文题面): 有一个有若干个密码(每个密码都可以开箱子)的密码箱,密码是在$0$到$n-1$的数中的,且所有的密码都满足一个 ...

  3. 【BZOJ 2216】【POI 2011】Lightning Conductor

    http://www.lydsy.com/JudgeOnline/problem.php?id=2216 学习了一下决策单调性. 这道题决策单调性比较明显,不详细证了. 对于一个决策i,如果在i之前的 ...

  4. 【BZOJ 2212】【POI 2011】Tree Rotations

    http://www.lydsy.com/JudgeOnline/problem.php?id=2212 自下而上贪心. 需要用权值线段树来记录一个权值区间内的出现次数. 合并线段树时统计逆序对的信息 ...

  5. bzoj 2276 [ Poi 2011 ] Temperature —— 单调队列

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2276 维护 l 递减的单调队列,队头的 l > 当前的 r 就出队,因为不能是连续一段 ...

  6. [ POI 2011 ] Party

    \(\\\) \(Description\) 给定一张 \(N\ (\ N\equiv 0\pmod{3}\ )\) 个节点,,\(M\)条边的图,并且保证该图存在一个大小至少为\(\frac{2}{ ...

  7. 洛谷 P3515 [ POI 2011 ] Lightning Conductor —— 决策单调性DP

    题目:https://www.luogu.org/problemnew/show/P3515 决策单调性... 参考TJ:https://www.cnblogs.com/CQzhangyu/p/725 ...

  8. Solution -「POI 2011」「洛谷 P3527」MET-Meteors

    \(\mathcal{Description}\)   Link.   给定一个大小为 \(n\) 的环,每个结点有一个所属国家.\(k\) 次事件,每次对 \([l,r]\) 区间上的每个点点权加上 ...

  9. POI题解整合

    我也不知道为啥我就想把POI的题全都放到一篇blog里写完. POI 2005 SAM-Toy Cars 贪心,每次选下次出现最晚的. POI 2006 KRA-The Disks 箱子位置单调,所以 ...

随机推荐

  1. JSON.parseObject将json字符串转换为bean类,是否大小写敏感区分---https://blog.csdn.net/mathlpz126/article/details/80684034

    JSON.parseObject将json字符串转换为bean类,是否大小写敏感区分 https://blog.csdn.net/mathlpz126/article/details/80684034

  2. hdu3461

    题意描述:有一个类似滚轮式的密码锁放在一排共n个,有m种操作每次操作一个区间,且此次操作后的所有密码相同,问最多能形成多少种密码 解决:将区间分为可变部分和不可变部分,没当有可变部分时候总区间数要减去 ...

  3. Promise 异步编程

    //1.解决异步回调问题 //1.1 如何同步异步请求 //如果几个异步操作之间并没有前后顺序之分,但需要等多个异步操作都完成后才能执行后续的任务,无法实现并行节约时间 const fs = requ ...

  4. 关于 Neo4j 属性个数的限制

    关于 Neo4j 属性个数的限制 目前累积统计它有34.4亿个节点,344亿的关系,和6870亿条属性. 社区版,Neo4j对 数据库内 节点.关系 上的属性名个数是有限制的.数据库中至多存在687亿 ...

  5. 如何用js往html页面拼接一个div包括div的各种常用属性

    $("#div").append("<table><tr align='center'>" +"<td >&quo ...

  6. [bzoj1070][SCOI2007]修车[ 网络流]

    把每个工人拆成N个点.记为A[i,j]表示第i个工人修倒数第j辆车.每个车跟所有N*M个工人拆出的点连边.流量为1,费用为$time[i,j]*k$.源和每辆车连边,N*M个点和汇连边,流量都为1,费 ...

  7. Javaweb中文乱码问题

    request.setCharacterEncoding("utf-8");必须写在获得参数之前,即request.getParameter();之前

  8. Parallelized coherent read and writeback transaction processing system for use in a packet switched cache coherent multiprocessor system

    A multiprocessor computer system is provided having a multiplicity of sub-systems and a main memory ...

  9. C++ - 模板函数须要类型转换时使用友元(friend)模板函数

    模板函数须要类型转换时使用友元(friend)模板函数 本文地址: http://blog.csdn.net/caroline_wendy/article/details/24357301 非模板函数 ...

  10. 网络协议IPV6基础知识点集锦

    由于互联网的快速发展与普及,原有的IPV4地址已不能满足网络用户的需求,虽然NAT可以缓解IPV4地址的耗尽,但NAT破坏了网络环境的开放.透明以及端到端的特性,因此IPV6地址协议应运而生. IPV ...