Bzoj 2525 [Poi2011]Dynamite
2525: [Poi2011]Dynamite
Time Limit: 30 Sec Memory Limit: 128 MB
Submit: 240 Solved: 120
[Submit][Status][Discuss]
Description
某个点上的引线被点燃后的1单位时间内,在树上和它相邻的点的引线会被点燃。如果一个有炸 药的点的引信被点燃,那么这个点上的炸 药会爆炸。
求引爆所有炸 药的最短时间。 输入:
第一行是两个整数N,M。(1<=m<=n<=300000)
接下来一行有N个整数Di,第I个数为1表示该点有炸 药。
接下来N-1行每行有两个数A,B,表示A和B之间有一条边。
输出:
最短时间。
样例解释:
点燃3,5上的引线。
Input
Output
Sample Input
1 0 1 1 0 1 1
1 3
2 3
3 4
4 5
5 6
5 7
Sample Output
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <map>
#include <set>
#include <vector>
#define N 300005
using namespace std;
int n,a[N],zz,m;
struct no
{
int to,next;
}road[N*];
void build(int x,int y)
{
zz++;
road[zz].to=y;
road[zz].next=a[x];
a[x]=zz;
}
int bom[N];
int size[N],fa[N];
void dfs1(int x)
{
size[x]=;
for(int i=a[x];i>;i=road[i].next)
{
int y=road[i].to;
if(y==fa[x])continue;
fa[y]=x;
dfs1(y);
size[x]+=size[y];
}
}
int sum,f[N],c[N];
void dfs(int x,int t)
{
if(size[x]==)
{
if(bom[x])
{
c[x]=;
f[x]=;
if(t==)
{
sum++;
f[x]=;
c[x]=;
}
}
else
{
c[x]=-;
f[x]=-;
}
return;
}
int mn=0x7fffffff,mx=-;
bool yx=;
for(int i=a[x];i>;i=road[i].next)
{
int y=road[i].to;
if(y==fa[x])continue;
dfs(y,t);
if(c[y]==-)continue;
yx=;
if(c[y]==)
{
if(f[y]+<=t) mn=min(mn,f[y]+);
} else
mx=max(mx,f[y]+);
}
if(yx)
{
c[x]=-;f[x]=-;
if(bom[x])
{
c[x]=;
f[x]=;
if(t==)
{
sum++;
c[x]=;
}
}
return;
}
if(mx==-&&mn!=0x7fffffff)
{
c[x]=;
f[x]=mn;
return;
}
if(mx==-&&mn==0x7fffffff)
{
if(bom[x])
{
c[x]=;
f[x]=;
if(t==)
{
sum++;
f[x]=;
c[x]=;
}
}
else
{
c[x]=-;
f[x]=-;
}
return;
}
if(mn==0x7fffffff)
{
if(mx>=t)
{
sum++;
f[x]=;
c[x]=;
}
else
{
c[x]=;
f[x]=mx;
}
return;
}
if(mn+mx<=t)
{
c[x]=;
f[x]=mn;
return;
}
if(mx>=t)
{
sum++;
f[x]=;
c[x]=;
}
else
{
c[x]=;
f[x]=mx;
}
}
bool check(int k)
{
memset(c,,sizeof(c));
memset(f,,sizeof(f));
sum=;
dfs(,k);
if(c[]==)sum++;
return sum<=m;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)
{
scanf("%d",&bom[i]);
}
for(int i=;i<n;i++)
{
int x,y;
scanf("%d%d",&x,&y);
build(x,y);
build(y,x);
}
dfs1();
int li=,ri=n,mid;
while(li<=ri)
{
mid=(li+ri)>>;
if(check(mid)) ri=mid-;
else li=mid+;
}
printf("%d\n",ri+);
return ;
}
Bzoj 2525 [Poi2011]Dynamite的更多相关文章
- 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] ...
- 【BZOJ2525】[Poi2011]Dynamite 二分+树形DP
[BZOJ2525][Poi2011]Dynamite Description Byteotian Cave的结构是一棵N个节点的树,其中某些点上面已经安置了炸.药,现在需要点燃M个点上的引线引爆所有 ...
- BZOJ 2530 Poi2011 Party 【枚举】
BZOJ 2530 Poi2011 Party Description Byteasar intends to throw up a party. Naturally, he would like i ...
- [bzoj 2216] [Poi2011] Lightning Conductor
[bzoj 2216] [Poi2011] Lightning Conductor Description 已知一个长度为n的序列a1,a2,-,an. 对于每个1<=i<=n,找到最小的 ...
- 【BZOJ2525】[Poi2011]Dynamite(二分,树形dp)
[BZOJ2525][Poi2011]Dynamite Description Byteotian Cave的结构是一棵N个节点的树,其中某些点上面已经安置了炸.药,现在需要点燃M个点上的引线引爆所有 ...
- [BZOJ 2212] [Poi2011] Tree Rotations 【线段树合并】
题目链接:BZOJ - 2212 题目分析 子树 x 内的逆序对个数为 :x 左子树内的逆序对个数 + x 右子树内的逆序对个数 + 跨越 x 左子树与右子树的逆序对. 左右子树内部的逆序对与是否交换 ...
- [BZOJ 2350] [Poi2011] Party 【Special】
题目链接: BZOJ - 2350 题目分析 因为存在一个 2/3 n 大小的团,所以不在这个团中的点最多 1/3 n 个. 牺牲一些团内的点,每次让一个团内的点与一个不在团内的点抵消删除,最多牺牲 ...
随机推荐
- C# 事件详解
1.事件的本质是什么 答:事件是委托的包装器,就像属性是字段的包装器一样 2.为什么有了委托还有有事件 委托可以被访问就可以被执行,事件则只能在类的内部执行 3.事件要怎么声明 a.明一个委托 //委 ...
- 微信小程序把玩(十二)text组件
原文:微信小程序把玩(十二)text组件 通常文本设置要不在wxml中设置,再要不就是通过weml绑定在js中设置文字. wxml <view > <text>我是文本组件&l ...
- HTML5 拖放并删除效果的简单实现
Html5 支持元素drag drop的功能需求,以后实现这类效果会简单很多.. 详细的文档说明在这里 代码如下所示:
- C++迭代器 iterator
1. 迭代器(iterator)是一中检查容器内元素并遍历元素的数据类型.(1) 每种容器类型都定义了自己的迭代器类型,如vector:vector<int>::iterator iter ...
- 什么是Android NDK
1.NDK是一系列工具的集合. NDK提供了一系列的工具,帮助开发者快速开发C(或C++)的动态库,并能自动将so和java应用一起打包成apk.这些工具对开发者的帮助是巨大的. NDK集成了交叉编译 ...
- C#调用Delphi Dll返回字符串的示例(使用Move才能拷贝字符串)
//----------------------Delphi------------------- procedure GetSqlData(ASource: PChar; ADest: PChar; ...
- qt 自动重启(两种方法)
所谓自动重启就是程序自动关闭后在重新打开: 一般一个qt程序main函数如下: int main(int argc, char* argv[]) { QApplication app(argc, ar ...
- CMake编译如何解决[-Werror,-Wformat-security] 问题
在用Android Studio进行Android开发时,常常采用 java代码调用C++代码,即JNI调用native的开发模式. 在上层build.gradle编译脚本里面可以指定C++代码的编译 ...
- 30442数据操纵语言DML
5.5 SQL的数据操纵功能 5.5.1 数据插入 使用CREATE语句创建的数据表还只是一个“空壳”,表中没有任何数据.利用SQL语言提供的INSERT语句可以完成向数据表插入数据的任务. INSE ...
- Spark —— 高可用集群搭建
一.集群规划 这里搭建一个3节点的Spark集群,其中三台主机上均部署Worker服务.同时为了保证高可用,除了在hadoop001上部署主Master服务外,还在hadoop002和hadoop00 ...