2018.09.26洛谷P1084 疫情控制(二分+倍增)
传送门
好题啊。
题目要求的最大值最小,看到这里自然想到要二分答案。
关键在于怎么检验。
显然对于每个点向根走比向叶节点更优。
因此我们二分答案之后,用倍增将每个点都向上跳到跳不动为止。
这时我们check一下是不是以1连向的点构成的子树都被管辖了。
如果不是我们将可以跳到根节点且还能继续走一截的点记下来,把没有被管辖的与1相连的节点记下来。
然后一个一个判能否合法就行了。
代码:
#include<bits/stdc++.h>
#define N 50005
using namespace std;
inline int read(){
int ans=0;
char ch=getchar();
while(!isdigit(ch))ch=getchar();
while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
return ans;
}
int n,m,first[N],cnt=0,tot1=0,tot2=0,st[N][21],q[N];
int dis[N][21];
bool vis[N];
struct edge{int v,next,w;}e[N<<1];
struct Node{int id,res;}a[N],b[N];
inline void add(int u,int v,int w){e[++cnt].v=v,e[cnt].w=w,e[cnt].next=first[u],first[u]=cnt;}
inline void dfs(int p){
for(int i=1;i<=20;++i)st[p][i]=st[st[p][i-1]][i-1],dis[p][i]=dis[p][i-1]+dis[st[p][i-1]][i-1];
for(int i=first[p];i;i=e[i].next){
int v=e[i].v;
if(v==st[p][0])continue;
dis[v][0]=e[i].w,st[v][0]=p,dfs(v);
}
}
inline void dfs1(int p){
if(vis[p])return;
vis[p]=true;
bool f=false;
for(int i=first[p];i;i=e[i].next){
int v=e[i].v;
if(v==st[p][0])continue;
f=true;
dfs1(v),vis[p]&=vis[v];
}
if(!f)vis[p]=false;
}
inline bool cmp(Node a,Node b){return a.res<b.res;}
inline bool check(int mid){
tot1=tot2=0;
for(int i=1;i<=n;++i)vis[i]=0;
for(int i=1;i<=m;++i){
int pos=q[i],sum=0;
for(int j=20;~j;--j)if(st[pos][j]>1&&sum+dis[pos][j]<=mid)sum+=dis[pos][j],pos=st[pos][j];
if(st[pos][0]==1&&sum+dis[pos][0]<=mid)a[++tot1]=(Node){pos,mid-sum-dis[pos][0]};
else vis[pos]=1;
}
dfs1(1);
if(vis[1])return true;
for(int i=first[1];i;i=e[i].next){
int v=e[i].v;
if(!vis[v])b[++tot2]=(Node){v,e[i].w};
}
if(tot1<tot2)return false;
sort(a+1,a+tot1+1,cmp),sort(b+1,b+tot2+1,cmp);
int pos=1;
for(int i=1;i<=tot1;++i){
if(!vis[a[i].id])vis[a[i].id]=1;
else if(a[i].res>=b[pos].res)vis[b[pos].id]=true;
while(pos<=tot2&&vis[b[pos].id])++pos;
if(pos>tot2)return true;
}
return false;
}
int main(){
n=read();
for(int i=1;i<n;++i){
int u=read(),v=read(),w=read();
add(u,v,w),add(v,u,w);
}
m=read();
for(int i=1;i<=m;++i)q[i]=read();
dfs(1);
int l=0,r=1e9,ans=-1;
while(l<=r){
int mid=l+r>>1;
if(check(mid))r=mid-1,ans=mid;
else l=mid+1;
}
printf("%d",ans);
return 0;
}
2018.09.26洛谷P1084 疫情控制(二分+倍增)的更多相关文章
- 洛谷 P1084 疫情控制 —— 二分+码力
题目:https://www.luogu.org/problemnew/show/P1084 5个月前曾经写过一次,某个上学日的深夜,精疲力竭后只有区区10分,从此没管... #include< ...
- 2018.09.26洛谷P3957 跳房子(二分+单调队列优化dp)
传送门 表示去年考普及组的时候失了智,现在看来并不是很难啊. 直接二分答案然后单调队列优化dp检验就行了. 注意入队和出队的条件. 代码: #include<bits/stdc++.h> ...
- 洛谷P1084 疫情控制(NOIP2012)(二分答案,贪心,树形DP)
洛谷题目传送门 费了几个小时杠掉此题,如果不是那水水的数据的话,跟列队的难度真的是有得一比... 话说蒟蒻仔细翻了所有的题解,发现巨佬写的都是倍增,复杂度是\(O(n\log n\log nw)\)的 ...
- [NOIP2012] 提高组 洛谷P1084 疫情控制
题目描述 H 国有 n 个城市,这 n 个城市用 n-1 条双向道路相互连通构成一棵树,1 号城市是首都, 也是树中的根节点. H 国的首都爆发了一种危害性极高的传染病.当局为了控制疫情,不让疫情扩散 ...
- NOIP2012 洛谷P1084 疫情控制
Description: H 国有 n 个城市,这 n 个城市用 n-1 条双向道路相互连通构成一棵树,1 号城市是首都,也是树中的根节点. H 国的首都爆发了一种危害性极高的传染病.当局为了控制疫情 ...
- 洛谷P1084 疫情控制 [noip2012] 贪心+树论+二分答案 (还有个小bugQAQ
正解:贪心+倍增+二分答案 解题报告: 正好想做noip的题目然后又想落实学长之前讲的题?于是就找上了这题 其实之前做过,70,然后实在细节太多太复杂就不了了之,现在再看一遍感觉又一脸懵了... 从标 ...
- 2018.09.26 洛谷P2464 [SDOI2008]郁闷的小J(map+vector)
传送门 本来出题人出出来想考数据结构的. 但是我们拥有map+vector/set这样优秀的STL,因此直接用map离散化,vector存下标在里面二分找答案就行了. 代码: #include< ...
- 洛谷P1084 疫情控制(贪心+倍增)
这个题以前写过一遍,现在再来写,感觉以前感觉特别不好写的细节现在好些多了,还是有进步吧. 这个题的核心思想就是贪心+二分.因为要求最小时间,直接来求问题将会变得十分麻烦,但是如果转换为二分答案来判断可 ...
- 洛谷P1084 疫情控制
题目 细节比较多的二分+跟LCA倍增差不多的思想 首先有这样一个贪心思路,深度越低的检查点越好,而最长时间和深度具有单调性,即给定时间越长,每个军队能向更浅的地方放置检查点.因此可以考虑二分时间,然后 ...
随机推荐
- Redis 通用操作2
01, 一次设置多个键值 => mset key1 value1 key2 value2 key3 value3 ...... 02, 一次获取多个值 => mget ke1 key2 k ...
- 浮动float 摆放位置
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Spring MVC 自定义类型转换器
新建一个自定义转换器 import org.springframework.core.convert.converter.Converter; import org.springframework.s ...
- Spring @Trasactionl 失效, JDK,CGLIB动态代理
@Transaction: http://blog.csdn.net/bao19901210/article/details/41724355 Spring上下文: http://blog.csd ...
- python 3 属性查找与绑定方法
1.属性查找 类有两种属性:数据属性和函数属性 (1)类的数据属性是所有对象共享的 #类的数据属性是所有对象共享的,id都一样 class OldboyStudent: school='oldboy' ...
- UI5-文档-4.8-Translatable Texts
在这一步中,我们将UI的文本移动到一个单独的资源文件中. 这样,他们都在一个中心位置,可以很容易地翻译成其他语言.这个国际化过程(简称i18n)是在SAPUI5中通过使用一种特殊的资源模型和标准的数据 ...
- python之函数嵌套与闭包
一:函数的嵌套:在函数内部在定义一个函数,一层套一层 def father(name): print("from father %s" %name) def son(): prin ...
- linux系统安装中文支持,解决中文乱码问题
怎么设置Linux系统中文语言,这是很多小伙伴在开始使用Linux的时候,都会遇到一个问题,就是终端输入命令回显的时候中文显示乱码.出现这个情况一般是由于没有安装中文语言包,或者设置的默认语言有问题导 ...
- Tomcat SSL配置及Tomcat CA证书安装
Tomcat既可以作为独立的Servlet容器,也可以作为其他HTTP服务器附加的Servlet容器.如果Tomcat在非独立模式下工作, 通常不必配置SSL,由它从属的HTTP服务器来实现和客户的S ...
- webpack项目在开发环境中使用静态css文件
webpack项目在开发环境中使用静态css文件 在webpack项目(本人使用的 vue-cli-webpack )中,需要引入 css 或 scss等样式文件时,本人目前知道的,通常有以下几种方法 ...