bzoj-2525 Dynamite
Byteotian Cave的结构是一棵N个节点的树,其中某些点上面已经安置了烟火,现在需要点燃M个点上的引线引爆所
有的烟火。某个点上的引线被点燃后的1单位时间内,在树上和它相邻的点的引线会被点燃。如果一个有烟火的点
的引信被点燃,那么这个点上的烟火会爆炸。求引爆所有烟火的最短时间。
1<=m<=n<=300000
Sample Input
7 2
1 0 1 1 0 1 1
1 3
2 3
3 4
4 5
5 6
5 7
Sample Output
1
可以发现实际上要求的就是选择点到所有烟火点的最大距离最小,这个可以二分答案,然后我就不会做了
一个说法是:如果选择的代价相等那么就是贪心,如果选择代价不等那么就是dp
f[i] 以i为根的子树中已经引爆的点离i最近的距离
g[i] 以i为根的子树中未引爆的点离i最远的距离
当发现一个未爆点,我们尽量找一个离它远的点(当然限制条件)的来引爆点
也就是说尽量向上走。
但对于根要特殊考虑下,因为根上面是没有结点了的。但if(g[1]+f[1]>limit)
则1这个点也要放引爆
对于其它点
if(f[i]+g[i]<=mid) g[i]=INF
if(g[i]==mid) 必须引爆x
/*
f[i] 以i为根的子树中已经引爆的点离i最近的距离
g[i] 以i为根的子树中未引爆的点离i最远的距离
回溯到每个节点时,优先考虑用另一个儿子中的点覆盖其他儿子
if(f[i]+g[i]<=mid) g[i]=INF
if(g[i]==mid) 必须引爆x
*/ #include <iostream>
#include <cstdio>
#include <cstring>
#define INF 1000000000
#define maxn 300005
using namespace std;
int n,m;
int a[maxn];
int ans;
struct edge
{
int to,ne;
}b[maxn*2];
int k=0,head[maxn];
int f[maxn],g[maxn];
int limit;
int num=0,op1=0;
inline int read()
{
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){ if(ch=='-') f=-1; ch=getchar(); }
while(ch>='0'&&ch<='9'){ x=x*10+ch-'0'; ch=getchar(); }
return x*f;
}
void add(int u,int v)
{
k++;
b[k].to=v; b[k].ne=head[u]; head[u]=k;
}
void dfs(int x,int pre)
{
f[x]=INF; //以i为根的子树中已经引爆的点离i最近的距离
if(a[x])
g[x]=0; //这以i为根的子树中未引爆的点离i最远的距离
else
g[x]=-INF;
for(int i=head[x];i!=-1;i=b[i].ne)
if(b[i].to!=pre)
{
dfs(b[i].to,x);
f[x]=min(f[x],f[b[i].to]+1);//找一个离x最近的引爆点
g[x]=max(g[x],g[b[i].to]+1);//一个离x最远的未引爆点
}
if(g[x]+f[x]<=limit)
//以x为根的子树,存在一个引爆点可以在规定时间内引爆那些未引爆点
g[x]=-INF;
if(g[x]==limit)
//离x最远的一个未能被引爆的点离x的距离=limit,说明x点必须被点燃
{
f[x]=0,g[x]=-INF,num++;
}
}
bool check(int x)
{
if(!x) return op1<=m;
limit=x; num=0;
dfs(1,0);
if(g[1]+f[1]>limit)
num++;
return num<=m;
}
void getans()
{
int l=0,r=n,mid;
ans=n;
while(l<=r)
{
mid=(l+r)>>1;
if(check(mid)) ans=mid,r=mid-1;
else l=mid+1;
}
}
int main()
{
memset(head,-1,sizeof(head));
n=read(); m=read();
for(int i=1;i<=n;i++)
{
a[i]=read();
if(a[i]) op1++;
}
int x,y;
for(int i=1;i<n;i++)
{
x=read(); y=read();
add(x,y); add(y,x);
}
getans();
printf("%d\n",ans);
return 0;
}
bzoj-2525 Dynamite的更多相关文章
- Bzoj 2525 [Poi2011]Dynamite
2525: [Poi2011]Dynamite Time Limit: 30 Sec Memory Limit: 128 MBSubmit: 240 Solved: 120[Submit][Sta ...
- bzoj 2525 [Poi2011]Dynamite 二分+树形dp
[Poi2011]Dynamite Time Limit: 30 Sec Memory Limit: 128 MBSubmit: 270 Solved: 138[Submit][Status][D ...
- BZOJ 2525 Poi2011 Dynamite 二分答案+树形贪心
题目大意:给定一棵树,有一些点是关键点,要求选择不超过mm个点.使得全部关键点到近期的选择的点距离最大值最小 二分答案,问题转化为: 给定一棵树,有一些点是关键点,要求选择最少的点使得每一个关键点到选 ...
- bzoj 2525: [Poi2011]Dynamite【二分+树上贪心】
一眼二分.然后重点是树上贪心部分 长得像dp一样,设mn为子树内已炸点的最浅点,mx为子树内没有炸并且需要炸的最深点,然后转移直接从子树继承即可 然后是判断当前u点是否需要炸,当mx[u]+mn[u] ...
- 【BZOJ】【1503】 【NOI2004】郁闷的出纳员
Splay Splay的模板题吧……妥妥的序列操作= =(好像有段时间没写过这种纯数据结构题了……) /************************************************ ...
- bzoj AC倒序
Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...
- BZOJ 2127: happiness [最小割]
2127: happiness Time Limit: 51 Sec Memory Limit: 259 MBSubmit: 1815 Solved: 878[Submit][Status][Di ...
- BZOJ 3275: Number
3275: Number Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 874 Solved: 371[Submit][Status][Discus ...
- BZOJ 2879: [Noi2012]美食节
2879: [Noi2012]美食节 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 1834 Solved: 969[Submit][Status] ...
- bzoj 4610 Ceiling Functi
bzoj 4610 Ceiling Functi Description bzoj上的描述有问题 给出\(n\)个长度为\(k\)的数列,将每个数列构成一个二叉搜索树,问有多少颗形态不同的树. Inp ...
随机推荐
- Androidstudio中添加jar包
1.先到网上下载你需要的jar包,下载下来后,将你Androidstudio中的项目切换为project 2.找到app下的libs,将你下载的jar包复制粘贴进去 3.jar包复制进去后,选中你的j ...
- Linux架构之Nginx 高可用
第53章 Nginx之高可用Keepalived 一.Keepalived高可用基本概述 1.1)什么是高可用 一般是指2台机器启动着完全相同的业务系统,当有一台机器down机了,另外一台服务器就能快 ...
- Linux架构之Nginx 常见问题
第54章 Nginx常见问题 一.Nginx多Sever优先级 在开始处理一个http请求时,nginx会取出header头中的Host变量,与nginx.conf中每个server的server_n ...
- rev 反向输出文件内容
1.命令功能 rev 按行反向输出文件内容 2.语法格式 rev file 3.使用范例 [root@localhost ~]# echo {a..k} >> test [root@lo ...
- 负载均衡(二)DNS负载均衡
一.DNS原理及解析过程详解 相信大家在平时工作中都离不开DNS解析,DNS解析是互联网访问的第一步,无论是使用笔记本浏览器访问网络还是打开手机APP的时候,访问网络资源的第一步必然要经过DNS解析流 ...
- 大数阶乘(N! Plus)问题
解题思路 将正整数N从1到N逐位相乘,即1 * 2 * 3...... * (N-1) * N.每次相乘后的值会存储到array[]中,其中一个数组元素存储值中的一位数.当值小于10时直接存储,值大于 ...
- [luogu]P3938 斐波那契[数学]
[luogu]P3938 斐波那契 题目描述 小 C 养了一些很可爱的兔子. 有一天,小 C 突然发现兔子们都是严格按照伟大的数学家斐波那契提出的模型来进行 繁衍:一对兔子从出生后第二个月起,每个月刚 ...
- scanf()函数原理
一.三点说明 1.用户输入的字符,会以ASCII码形式存储在键盘缓冲区:2.每调用一次scanf函数,就从键盘缓冲区读走一个字符,相当于清除缓冲区:3.若用户一次输入n个字符,则前n次调用scanf函 ...
- 搭建 .Net RabbitMQ 开发环境
开发环境,window 10 64位,VS2017,系统账号需要用administrator. 1 先需要安装erlang语言开发包,一路默认安装就是了,地址:http://www.erlang.or ...
- Django REST framework入门 (转自中文文档)
快速入门 我们将创建一个简单的允许管理员用户查看和编辑系统中的用户和组的API. 项目设置 创建一个名为 tutorial 的新django项目,然后启动一个名为 quickstart 的新app. ...