题意:给出一棵无根树,每个节点有一个权值,现在要让dfs序的前k个结点的最小值最大,求出这个值。

考虑二分答案,把>=答案的点标记为1,<答案的点标记为0,现在的任务时使得dfs序的前k个节点都为1.

考虑树形DP。

用dp[u]表示从节点u开始在子树中进行dfs最多可以经过多少个为1的结点,显然,若某一个子树中节点全为1,那么这个可以加到dp[u]中,此外还可以在不全为1的子树中挑选一个加到dp[u]上。

那么答案就是从标记为1的节点当做根,选两颗不完全子树和所有的完全子树(包括从父亲向上的部分)。

那么如果从父亲向上的部分是不完全子树呢,那等价于从这颗不完全子树上的一个深度最小的点做上面的计算一下。所以不需要考虑从父亲向上的部分是不完全子树这个情况。

时间复杂度O(nlogn).

  1. # include <cstdio>
  2. # include <cstring>
  3. # include <cstdlib>
  4. # include <iostream>
  5. # include <vector>
  6. # include <queue>
  7. # include <stack>
  8. # include <map>
  9. # include <bitset>
  10. # include <set>
  11. # include <cmath>
  12. # include <algorithm>
  13. using namespace std;
  14. # define lowbit(x) ((x)&(-x))
  15. # define pi acos(-1.0)
  16. # define eps 1e-
  17. # define MOD
  18. # define INF
  19. # define mem(a,b) memset(a,b,sizeof(a))
  20. # define FOR(i,a,n) for(int i=a; i<=n; ++i)
  21. # define FO(i,a,n) for(int i=a; i<n; ++i)
  22. # define bug puts("H");
  23. # define lch p<<,l,mid
  24. # define rch p<<|,mid+,r
  25. # define mp make_pair
  26. # define pb push_back
  27. typedef pair<int,int> PII;
  28. typedef vector<int> VI;
  29. # pragma comment(linker, "/STACK:1024000000,1024000000")
  30. typedef long long LL;
  31. int Scan() {
  32. int x=,f=;char ch=getchar();
  33. while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
  34. while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
  35. return x*f;
  36. }
  37. const int N=;
  38. //Code begin...
  39.  
  40. struct Edge{int p, next;}edge[N<<];
  41. int node[N], head[N], cnt=, dp[N], date[N], siz[N], tag[N], sum, n, K, ans;
  42. bool flag[N];
  43.  
  44. void add_edge(int u, int v){edge[cnt].p=v; edge[cnt].next=head[u]; head[u]=cnt++;}
  45. void dfs1(int x, int fa, int val){
  46. siz[x]=;
  47. if (node[x]<val) tag[x]=, ++sum;
  48. if (node[x]<val) flag[x]=true;
  49. for (int i=head[x]; i; i=edge[i].next) {
  50. int v=edge[i].p;
  51. if (v==fa) continue;
  52. dfs1(v,x,val); siz[x]+=siz[v]; tag[x]+=tag[v]; flag[x]|=flag[v];
  53. }
  54. }
  55. void dfs2(int x, int fa, int val){
  56. dp[x]=;
  57. int f=, s=;
  58. for (int i=head[x]; i; i=edge[i].next) {
  59. int v=edge[i].p;
  60. if (v==fa) continue;
  61. dfs2(v,x,val);
  62. if (!flag[v]) dp[x]+=siz[v];
  63. else if (node[v]>=val) {
  64. if (dp[v]>f) s=f, f=dp[v];
  65. else if (dp[v]>s) s=dp[v];
  66. }
  67. }
  68. dp[x]+=f;
  69. if (node[x]>=val) {
  70. if (tag[x]==sum) ans=max(ans,dp[x]+s+n-siz[x]);
  71. else ans=max(ans,dp[x]+s);
  72. }
  73. }
  74. bool check(int x){
  75. mem(siz,); mem(dp,); mem(flag,false); mem(tag,); sum=ans=;
  76. dfs1(,,x); dfs2(,,x);
  77. return ans>=K;
  78. }
  79. int main ()
  80. {
  81. int u, v;
  82. scanf("%d%d",&n,&K);
  83. FOR(i,,n) scanf("%d",node+i), date[i]=node[i];
  84. FO(i,,n) scanf("%d%d",&u,&v), add_edge(u,v), add_edge(v,u);
  85. sort(date+,date+n+);
  86. int l=, r=n+, mid;
  87. while (l<r) {
  88. mid=(l+r)>>;
  89. if (l==mid) break;
  90. if (check(date[mid])) l=mid;
  91. else r=mid;
  92. }
  93. printf("%d\n",date[l]);
  94. return ;
  95. }

Codeforces 627D Preorder Test(二分+树形DP)的更多相关文章

  1. 8VC Venture Cup 2016 - Final Round D. Preorder Test 二分 树形dp

    Preorder Test 题目连接: http://www.codeforces.com/contest/627/problem/D Description For his computer sci ...

  2. 【bzoj5174】[Jsoi2013]哈利波特与死亡圣器 二分+树形dp

    题目描述 给你一棵以1为根的有根树,初始除了1号点为黑色外其余点均为白色.Bob初始在1号点.每次Alice将其中至多k个点染黑,然后Bob移动到任意一个相邻节点,重复这个过程.求最小的k,使得无论B ...

  3. 【题解】hdu 3586 Information Disturbing 二分 树形dp

    题目描述 Information DisturbingTime Limit: 6000/3000 MS (Java/Others) Memory Limit: 131072/65536 K (Java ...

  4. codeforces 161D Distance in Tree 树形dp

    题目链接: http://codeforces.com/contest/161/problem/D D. Distance in Tree time limit per test 3 secondsm ...

  5. codeforces 337D Book of Evil (树形dp)

    题目链接:http://codeforces.com/problemset/problem/337/D 参考博客:http://www.cnblogs.com/chanme/p/3265913 题目大 ...

  6. HDU 3586 Information Disturbing(二分+树形dp)

    http://acm.split.hdu.edu.cn/showproblem.php?pid=3586 题意: 给定一个带权无向树,要切断所有叶子节点和1号节点(总根)的联系,每次切断边的费用不能超 ...

  7. HDU 5682 zxa and leaf 二分 树形dp

    zxa and leaf 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5682 Description zxa have an unrooted t ...

  8. bzoj 2067: [Poi2004]SZN【贪心+二分+树形dp】

    第一问就是Σ(deg[u]-1)/2+1 第二问是二分,判断的时候考虑第一问的贪心规则,对于奇度数的点,两两配对之后一条延伸到上面:对于欧度数的点,两两配对或者deg[u]-2的点配对,然后一条断在这 ...

  9. Codeforces 1276D - Tree Elimination(树形 dp)

    Codeforces 题面传送门 & 洛谷题面传送门 繁琐的简单树形 dp(大雾),要是现场肯定弃了去做 F 题 做了我一中午,写篇题解纪念下. 提供一种不太一样的思路. 首先碰到这样的题肯定 ...

随机推荐

  1. 20155322 2016-2017-2《Java程序设计》课程总结

    学号 2016-2017-2<Java程序设计>课程总结 (按顺序)每周作业链接汇总 预备作业一:浅谈对师生关系的看法以及对未来学习生活的展望 预备作业二:学习娄老师<做中学> ...

  2. js获取上月的最后一天

    一.问题: 在最近的开发中遇到一个需求,需要初始化默认时间为上月的最后一天 而在日历中这个值在每个月都不是固定的 二.分析: 问题可以转化为,获取指定月份时间的月末最后一天,下边是代码,供大家参考 f ...

  3. KDTable如何添加合计行?

    /** * 功能:添加合计行 * * @param table * 指定的KDTable * @param fields * 需要合计的列 */ public static void apendFoo ...

  4. Why HBase

    3.1.1,为什么选用HBases a)      容量巨大 HBase 的单表可以有百亿行.百万列,数据矩阵横向和纵向两个维度所支持的数据量级 都非常具有弹性.传统的关系型数据库,如 Oracle ...

  5. Ceph学习之路(二)之Ceph的工作原理及流程

    一.RADOS的对象寻址 Ceph 存储集群从 Ceph 客户端接收数据——不管是来自 Ceph 块设备. Ceph 对象存储. Ceph 文件系统.还是基于 librados 的自定义实现——并存储 ...

  6. 【JUC源码解析】LinkedBlockingQueue

    简介 一个基于链表的阻塞队列,FIFO的顺序,head指向的元素等待时间最长,tail指向的元素等待时间最短,新元素从队列尾部添加,检索元素从队列头部开始,队列的容量,默认是Integer#MAX_V ...

  7. cmake-index-3.11.4机翻

    index next | CMake » git-stage git-master latest release 3.13 3.12 3.11.4 3.10 3.9 3.8 3.7 3.6 3.5 3 ...

  8. 在Office 365 的如何给管理员赋予查看所有人邮箱的权限的Powershell

    连接至Office365 的Powershell Get-MsolUser -UserPrincipalName admin@***.partner.onmschina.cn //Get-MsolUs ...

  9. 所见即所得:七大无需编程的DIY开发工具

    现如今,各种DIY开发工具不断的出现,使得企业和个人在短短几分钟内就能完成应用的创建和发布,大大节省了在时间和资金上的投入.此外,DIY工具的出现,也帮助广大不具备专业知识和技术的“移动开发粉”创建自 ...

  10. Scrum立会报告+燃尽图 03

    此作业要求:[https://edu.cnblogs.com/campus/nenu/2018fall/homework/2190] 一.小组介绍 组长:王一可 组员:范靖旋,王硕,赵佳璐,范洪达,祁 ...