[Poi2011]Dynamite

[Poi2011]Dynamite

时间限制: 3 Sec  内存限制: 128 MB

题目描述

The Byteotian Cave is composed of  n chambers and n-1 corridors that connect them. For every pair of chambers there is unique way to move from one of them to another without leaving the cave. Dynamite charges are set up in certain chambers. A fuse is laid along every corridor. In every chamber the fuses from the adjacent corridors meet at one point, and are further connected to the dynamite charge if there is one in the chamber. It takes exactly one unit of time for the fuse between two neighbouring chambers to burn, and the dynamite charge explodes in the instant that fire reaches the chamber it is inside.

We would like to light the fuses in some m chambers (at the joints of fuses) in such a way that all the dynamite charges explode in the shortest time possible since the fuses are lit. Write a program that will determine the minimum such time possible.

Byteotian Cave的结构是一棵N个节点的树,其中某些点上面已经安置了Bomb,现在需要点燃M个点上的引线引爆所有的Bomb。

某个点上的引线被点燃后的1单位时间内,在树上和它相邻的点的引线会被点燃。如果一个有Bomb的点的引信被点燃,那么这个点上的Bomb会爆炸。
求引爆所有Bomb的最短时间。

输入:
第一行是两个整数N,M。(1<=m<=n<=300000)
接下来一行有N个整数Di,第I个数为1表示该点有Bomb。
接下来N-1行每行有两个数A,B,表示A和B之间有一条边。
输出:
最短时间。
样例解释: 
点燃3,5上的引线。 

输入

The first line of the standard input holds two integers n and m (1<=M<=N<=300000)

, separated by a single space, that denote, respectively, the number of chambers in the cave and the number of chambers in which fire can be set to the fuses. The chambers are numbered from 1 to n . The next line contains  n integers d1,d2…dn (Di属于{0,1}, separated by single spaces. If Di=1 , then there is dynamite in the -th chamber, and if di=0 , there is none. The following n -1 lines specify the corridors of the cave. Each of them holds two integers a,b (a<=a<b<=n), separated by a single space, denoting that there is a corridor connecting the chambers a and b . Every corridor appears exactly once in the description.

You may assume that in tests worth 10% of the points it holds additionally that n<= 10, while in tests worth 40% of the points it holds that N<=1000.

输出

The first and only line of the standard output should hold a single integer, equal to the minimum time it takes from lighting the fuses to the explosion of all the charges.

样例输入

7 2
1 0 1 1 0 1 1
1 3
2 3
3 4
4 5
5 6
5 7

样例输出

1

Solution:     一开始觉得落谷模拟赛一个题很像,直接打了个暴力发现只有40,一看发现数据范围不对QAQ,二分一下答案然后贪心就好,需要放就放,如果数量超过m说明不可行。  
 1 #pragma GCC optimize("O3")
 2 #include <iostream>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include <cstdio>
 6 using namespace std;
 7 #define N 300005
 8 int read() {
 9     int s=0,f=1;
10     char ch=getchar();
11     for( ; ch<‘0‘||ch>‘9‘; f=(ch==‘-‘)?-1:f,ch=getchar()) ;
12     for( ; ch>=‘0‘&&ch<=‘9‘; s=s*10+(ch^48),ch=getchar()) ;
13     return s*f;
14 }
15 int n,m,tot,r[N],deep[N],Bomb[N],L,R,Ans,son[N],num;
16 struct EDGE{int to,next;} c[N<<1];
17 void add(int x,int y) {
18     c[++tot]=(EDGE){y,r[x]};
19     r[x]=tot;
20 }
21 int Judge[N],f[N];
22 //可以再往上传的长度 需要被炸得最长长度
23 void DFS(int u,int fa,int now) {
24     int mx1=-0x5f5f5f5f,mx2=-0x5f5f5f5f;
25     if(Bomb[u]) mx1=0;
26     for(int i=r[u]; ~i; i=c[i].next) {
27         if(c[i].to!=fa) {
28             DFS(c[i].to,u,now);
29             if(Judge[c[i].to]==1) mx1=max(mx1,f[c[i].to]+1);
30             if(Judge[c[i].to]==2) mx2=max(mx2,f[c[i].to]-1);
31             if(Judge[c[i].to]==-1||num>m) {Judge[u]=-1; return ;}
32         }
33     }
34     if(mx1>mx2) {
35         if(mx1>=now) {
36             ++num,Judge[u]=2,f[u]=now;
37             if(num>m) Judge[u]=-1;
38         } else Judge[u]=1,f[u]=mx1;
39     } else Judge[u]=2,f[u]=mx2;
40 }
41 bool check(int now) {
42     num=0;
43     DFS(1,1,now);
44     if(Judge[1]==-1) return false;
45     if(Judge[1]==1&&f[1]>=0) ++num;
46     return num<=m;
47 }
48 int main() {
49     R=n=read(),m=read();
50     memset(r,0xff,sizeof(r));
51     for(int x,i=1; i<=n; ++i) Bomb[i]=read();
52     for(int x,y,i=1; i<n; ++i) x=read(),y=read(),add(x,y),add(y,x);
53     while(L<=R) {
54         int mid=(L+R)>>1;
55         if(check(mid))Ans=mid,R=mid-1;
56         else L=mid+1;
57     } printf("%d",Ans);
58     return 0;
59 }
 
时间: 2024-08-25 09:36:56

[Poi2011]Dynamite的相关文章

【BZOJ2525】[Poi2011]Dynamite 二分+树形DP

[BZOJ2525][Poi2011]Dynamite Description Byteotian Cave的结构是一棵N个节点的树,其中某些点上面已经安置了炸.药,现在需要点燃M个点上的引线引爆所有的炸.药. 某个点上的引线被点燃后的1单位时间内,在树上和它相邻的点的引线会被点燃.如果一个有炸.药的点的引信被点燃,那么这个点上的炸.药会爆炸. 求引爆所有炸.药的最短时间. 输入: 第一行是两个整数N,M.(1<=m<=n<=300000) 接下来一行有N个整数Di,第I个数为1表示该点

BZOJ 2525 [Poi2011]Dynamite 二分+树形贪心

题意: n个点,一棵树,有些点是关键点,可以将m个点染色. 求所有关键点到最近的被染色点的距离的最大值最小. 解析: 反正从这道题我是学了一种做题思路? 大爷讲课的时候说的:一般选择某些点的代价相同的话都是贪心,代价不同的话一般都是DP. 想想也挺对的,不过就是没有感悟到过? 反正这题考试的时候我是直接D了贪心的- -! 忘了为啥D了. 显然最大值最小我们需要二分一下这个值. 然后接下来我们从下往上扫整棵树. 节点的状态有几个? 第一种是 子树内没有不被覆盖的关键点,并且子树中有一个节点的贡献可

BZOJ 2525 Poi2011 Dynamite 二分答案+树形贪心

题目大意:给定一棵树,有一些点是关键点,要求选择不超过m个点,使得所有关键点到最近的选择的点距离最大值最小 二分答案,问题转化为: 给定一棵树,有一些点是关键点,要求选择最少的点使得每个关键点到选择的点的距离不超过limit 然后我们贪心DFS一遍 对于以一个节点为根的子树,有三种状态: 0.这棵子树中存在一个选择的点,这个选择的点的贡献还能继续向上传递 1.这棵子树中存在一个未被覆盖的关键点,需要一些选择的点去覆盖他 2.这棵子树中既没有能继续向上传递的选择的点也不存在未覆盖的关键点 是不是少

bzoj 2525: [Poi2011]Dynamite【二分+树上贪心】

一眼二分.然后重点是树上贪心部分 长得像dp一样,设mn为子树内已炸点的最浅点,mx为子树内没有炸并且需要炸的最深点,然后转移直接从子树继承即可 然后是判断当前u点是否需要炸,当mx[u]+mn[u]<=mid,当前子树可以自己消化,所以mx[u]=-inf:否则,就需要在u炸一下 #include<iostream> #include<cstdio> using namespace std; const int N=300005; int n,m,h[N],cnt,d[N]

联赛之前的题表(已完成)汇总(可能有遗漏)

联赛之前的搞搞(其实是懒得分类) 博弈论 poj3537 poj1704 hdu5996两个插头 HDU1693 Eat the Trees COGS1283. [HNOI2004] 邮递员kdtree板子1941: [Sdoi2010]Hide and Seek旋转卡壳 pj2187凸包 cogs896 bzoj2829 信用卡凸包莫比乌斯反演基础 bzoj 4173 zhao gui lv bzoj 3529 mobiwus bzoj 4407 mobiwus bzoj 2818 mobiw

BZOJ2212: [Poi2011]Tree Rotations

2212: [Poi2011]Tree Rotations Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 391  Solved: 127[Submit][Status] Description Byteasar the gardener is growing a rare tree called Rotatus Informatikus. It has some interesting features: The tree consists o

【BZOJ2216】[Poi2011]Lightning Conductor 决策单调性

[BZOJ2216][Poi2011]Lightning Conductor Description 已知一个长度为n的序列a1,a2,...,an.对于每个1<=i<=n,找到最小的非负整数p满足 对于任意的j, aj < = ai + p - sqrt(abs(i-j)) Input 第一行n,(1<=n<=500000)下面每行一个整数,其中第i行是ai.(0<=ai<=1000000000) Output n行,第i行表示对于i,得到的p Sample I

BZOJ2213: [Poi2011]Difference

2213: [Poi2011]Difference Time Limit: 10 Sec  Memory Limit: 32 MBSubmit: 343  Solved: 108[Submit][Status] Description A word consisting of lower-case letters of the English alphabet ('a'-'z') is given. We would like to choose a non-empty contiguous (

【BZOJ2529】[Poi2011]Sticks 贪心

[BZOJ2529][Poi2011]Sticks Description 给出若干木棍,每根木棍有特定的颜色和长度.问能否找到三条颜色不同的木棍构成一个三角形.(注意这里所说的三角形面积要严格大于0) 第一行给出一个整数k(3<=k<=50),表示颜色的种数.这k种颜色被标号为1至k.接下来k行,第i+1描述颜色为i的木棍的信息.首先一个整数Ni(1<=Ni<=10^6)表示颜色为i的木棍的数量.接下来Ni个整数,表示这Ni根木棍各自的长度.所有木棍的长度<=10^9.总木