\(\\\)

\(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\)


#include<cmath>
#include<cstdio>
#include<cctype>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define N 300010
#define R register
#define gc getchar
using namespace std; int n,m,tot,cnt,d[N],hd[N];
int f[N],tag[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;
} 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;
} inline void dfs(int u,int fa,int lim){
int mn=-1,mx=d[u]-1;
for(R int i=hd[u];i;i=e[i].nxt)
if(e[i].to!=fa) dfs(e[i].to,u,lim);
for(R int i=hd[u];i;i=e[i].nxt)
if(e[i].to!=fa){
if(tag[e[i].to]==0) mn=max(mn,f[e[i].to]-1);
else if(tag[e[i].to]==1) mx=max(mx,f[e[i].to]+1);
}
if(mn<mx){
if(mx==lim){++cnt; f[u]=lim;tag[u]=0;}
else{f[u]=mx;tag[u]=1;}
}
else if(mn!=-1){f[u]=mn; tag[u]=0;}
else{f[u]=0;tag[u]=2;}
} inline bool valid(int x){
cnt=0; dfs(1,0,x);
if(tag[1]==1) ++cnt;
return cnt<=m;
} int main(){
n=rd(); m=rd();
for(R int i=1;i<=n;++i) d[i]=rd();
for(R int i=1,u,v;i<n;++i){
u=rd(); v=rd(); add(u,v); add(v,u);
}
int l=0,r=n;
while(l<r){
int mid=((l+r)>>1);
valid(mid)?r=mid:l=mid+1;
}
printf("%d\n",l);
return 0;
}

[ 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. linux安装java mysql tomcat 环境

    安装jdk: 1. 查看系统版本 uname -a 2.查看操作系统 cat  /proc/version 3.上传安装文件到指定目录   tar -zxvf jdkxxx. 4.修改配置文件  vi ...

  2. Eddy's mistakes

    Problem Description Eddy usually writes  articles ,but he likes mixing the English letter uses, for ...

  3. kendo Cannot read property 'call' of undefined

    造成这个错误的原因是在 必须有id的定义

  4. tomcat这种http服务器,是能接收到客户端的断开信息的,并能打印出来

    如,tomcat的运行文件 DEBUG -- CLOSE BY CLIENT STACK TRACE

  5. python 除法总返回浮点

    python 除法总返回浮点,要返回整型需要用//: print(type(4/2),type(4//2)) #<class 'float'> <class 'int'>

  6. 使用JSONObject 深度序列化和反序列化

    JSONObject 和JSONArray 是json-lib.jar里面最经常使用的两个类,分别能够对对象和数组(集合)进行序列化和反序列化,结构清晰命了,简单易用,功能强大,效率比較高,使用至今一 ...

  7. 小议:怎样解决创建Web Application失败问题?

    我们都知道微软建议部署SharePoint2013环境的内存至少是12GB.可是有些小型企业在部署On Premise的环境时因为预算有限,仅仅能使用内存是8GB的环境来部署SharePoint201 ...

  8. [LeetCode][Java] N-Queens II

    题目: Follow up for N-Queens problem. Now, instead outputting board configurations, return the total n ...

  9. swift 2.0语法 元组

    import UIKit /*: 元祖 * 可以将多个值保存在一起 * 格式: (数值1, 数值2, 数值3) * 特点: 元祖可以保存不同数据类型的值 * 用途: 在C/OC中如果一个函数想返回多个 ...

  10. linux (debian) 配置静态ip

    在局域网内使用动态ip分配,机器动态的获取 ip地址.可是我使用ssh登录的时候.总是断线. 后来发现,原来机器总是在两个ip地址192.168.2.203 和192.168.2.228之间切换.用s ...