题目大意

  给出一棵n个节点的树,根是1,要在除根节点以外的点建立检查点,使得从每条根到叶子的路径上都至少存在一个检查点。检查点由军队来建立。初始军队的位置是给定的,移动军队走一条边需要花费这条边的权值的时间。现在要求一个方案,移动军队到某个最佳位置,使得总用时最少。

【数据范围】
保证军队不会驻扎在首都。
对于20%的数据,2≤ n≤ 10;
对于40%的数据,2 ≤n≤50,0<w <105
对于60%的数据,2 ≤ n≤1000,0<w <106
对于80%的数据,2 ≤ n≤10,000;
对于100%的数据,2≤m≤n≤50,000,0<w <109

  这道题目没有想象的那样难,先是二分答案,再用倍增,接着树形dp,然后是贪心地分配判断是否合法。

 #include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
using namespace std;
typedef long long LL;
const LL INF=1ll<<;
const int N=,D=;
int cnt,fir[N],nxt[N*];
int to[N*];LL val[N*];
LL dis[D][N],fa[D][N];
void addedge(register int a,register int b,LL w){
nxt[++cnt]=fir[a];
fir[a]=cnt;
val[cnt]=w;
to[cnt]=b;
}
int n,m,dep[N];
void Prepare(){
for(register int k=;k<=;k++)
for(register int i=;i<=n;i++){
fa[k][i]=fa[k-][fa[k-][i]];
dis[k][i]=dis[k-][i]+dis[k-][fa[k-][i]];
}
}
void DFS(register int x){
for(register int i=fir[x];i;i=nxt[i])
if(to[i]!=fa[][x]){
fa[][to[i]]=x;
dep[to[i]]=dep[x]+;
dis[][to[i]]=val[i];
DFS(to[i]);
}
}
int dp[N],st[N];
vector<LL>v[N];
void DP(register int x){
if(dep[x]>)
dp[x]=v[x].size();
else dp[x]=;
bool tmp=true,flag=false;
for(register int i=fir[x];i;i=nxt[i])
if(to[i]!=fa[][x]){
DP(to[i]);
tmp&=dp[to[i]];
flag=true;
}
dp[x]|=tmp&flag;
}
int ca,cb,p[N];
LL a[N],b[N],c[N];
bool Check(LL mid){
for(register int i=;i<=n;i++)
v[i].clear();
for(register int i=;i<=m;i++){
LL tmp=mid;register int x=st[i];
for(register int k=;k>=;k--)
if(dis[k][x]<=tmp){
if(fa[k][x]<=)continue;
tmp-=dis[k][x];
x=fa[k][x];
}
v[x].push_back(tmp);
}
DP();ca=cb=;
for(register int i=fir[],y;i;i=nxt[i]){
register int sz=v[y=to[i]].size(),z=;
if(!dp[y])b[++cb]=val[i],z=cb;
for(register int j=;j<sz;j++){
a[++ca]=v[y][j]-val[i];
c[ca]=z;
}
}
memset(p,,sizeof(p));
for(register int i=;i<=ca;i++){
if(!p[c[i]])p[c[i]]=i;
else if(a[p[c[i]]]>a[i])
p[c[i]]=i;
}
for(register int i=;i<=cb;i++)
if(p[i]&&b[i]>a[p[i]]){
b[i]=a[p[i]]=INF;
}
sort(a+,a+ca+);while(a[ca]==INF)ca--;
sort(b+,b+cb+);while(b[cb]==INF)cb--;
for(register int i=,j=;i<=ca;i++){
if(a[i]>=b[j])j++;
if(j>cb)return true;
}
return false;
} LL l,r,mid,w;
int main(){
freopen("blockade.in","r",stdin);
freopen("blockade.out","w",stdout);
scanf("%d",&n);
for(register int i=,a,b;i<n;i++){
scanf("%d%d%lld",&a,&b,&w);
addedge(a,b,w);
addedge(b,a,w);
}DFS();Prepare();
scanf("%d",&m);
for(register int i=;i<=m;i++)
scanf("%d",&st[i]);
l=;r=INF;
while(l<=r){
mid=(l+r)>>;
if(Check(mid))r=mid-;
else l=mid+;
}
if(l>INF)l=-;
printf("%lld\n",l);
return ;
}

基础算法(二分,贪心):NOIP 2012 疫情控制的更多相关文章

  1. 【NOIP 2012 疫情控制】***

    题目描述 H 国有 n 个城市,这 n 个城市用 n-1 条双向道路相互连通构成一棵树,1 号城市是首都, 也是树中的根节点. H 国的首都爆发了一种危害性极高的传染病.当局为了控制疫情,不让疫情扩散 ...

  2. NOIP 2012 疫情控制(二分+贪心+倍增)

    题解 二分时间 然后一个显然的事是一个军队向上爬的越高它控制的点越多 所以首先军队尽量往上爬. 当一个军队可以爬到根节点我们记录下它的剩余时间T和它到达根结点时经过的根节点的子节点son. 当一个军队 ...

  3. noip 2012 疫情控制

    /* 考试的时候没想出正解 也没打暴力 时间不够了 随便yy了几种情况按出现的先后顺序处理而没有贪心 的了20分 不粘了 正解是围绕首都的儿子来搞的 显然先二分答案 对于每个限定的最大时间 我们尝试着 ...

  4. 【NOIP】提高组2012 疫情控制

    [题意]n个点的树,1为根,要求删除一些点使得截断根节点和所有叶子结点的路径(不能删根,可以删叶子).有m支军队在m个点上,每时刻所有军队可以走一步,最终走到的地方就是删除的点,求最短时间. [算法] ...

  5. leetcode1552题解【二分+贪心】

    leetcode1552.两球之间的磁力 题目链接 算法 二分+贪心 时间复杂度O(nlogn + nlogm) 1.根据题意描述,我们需要将m个球放入到n个篮子中,根据题目中数据范围描述发现m &l ...

  6. 疫情控制 2012年NOIP全国联赛提高组(二分答案+贪心)

    P1084 疫情控制 题目描述 H 国有 n 个城市,这 n 个城市用 n-1 条双向道路相互连通构成一棵树,1 号城市是首都,也是树中的根节点. H 国的首都爆发了一种危害性极高的传染病.当局为了控 ...

  7. Codevs 1218 疫情控制 2012年NOIP全国联赛提高组

    1218 疫情控制 2012年NOIP全国联赛提高组 时间限制: 2 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description H 国有 n 个城市,这 ...

  8. Luogu 1084 NOIP2012 疫情控制 (二分,贪心,倍增)

    Luogu 1084 NOIP2012 疫情控制 (二分,贪心,倍增) Description H 国有 n 个城市,这 n 个城市用 n-1 条双向道路相互连通构成一棵树, 1 号城市是首都, 也是 ...

  9. 【noip 2012】提高组Day2T3.疫情控制

    Description H国有n个城市,这n个城市用n-1条双向道路相互连通构成一棵树,1号城市是首都,也是树中的根节点. H国的首都爆发了一种危害性极高的传染病.当局为了控制疫情,不让疫情扩散到边境 ...

随机推荐

  1. iOS开发——音频篇——音效的播放

    一.简单介绍 简单来说,音频可以分为2种 (1)音效 又称“短音频”,通常在程序中的播放时长为1~2秒 在应用程序中起到点缀效果,提升整体用户体验 (2)音乐 比如游戏中的“背景音乐”,一般播放时间较 ...

  2. 安装aptana插件报Error opening the editor. java.lang.NullPointerException

    Aptana的官方网站下载eclipse的插件:  http://update.aptana.com/update/studio/3.2/ ,可以在线安装也可以下载插件后再安装,我是以在线的形式安装的 ...

  3. Solr集群的搭建以及使用(内涵zookeeper集群的搭建指南)

    1   什么是SolrCloud SolrCloud(solr 云)是Solr提供的分布式搜索方案,当你需要大规模,容错,分布式索引和检索能力时使用 SolrCloud.当一个系统的索引数据量少的时候 ...

  4. LA 3902 Network(树上最优化 贪心)

    Network Consider a tree network with n <tex2html_verbatim_mark>nodes where the internal nodes ...

  5. 九度OJ 1527 首尾相连数组的最大子数组和 -- 动态规划

    题目地址:http://ac.jobdu.com/problem.php?pid=1527 题目描述: 给定一个由N个整数元素组成的数组arr,数组中有正数也有负数,这个数组不是一般的数组,其首尾是相 ...

  6. 《C语言学习笔记》指针数组及其应用

    C语言中,最灵活但又容易出错的莫过于指针了.而指针数组,是在C中很常见的一个应用.指针数组的意思是说,这个数组存储的所有对象都为指针.除了存储对象为指针,即一个地址外,其它操作和普通数组完全一样. # ...

  7. php ini_set('display_errors', $value)

    正常情况下,在开发模式中,把错误显示出来,方便纠正,但在布署模式中,就得把错误关闭: ini_set('display_errors', 1); // 开启 ini_set('display_erro ...

  8. Python3实现连接SQLite数据库的方法

    本文实例讲述了Python3实现连接SQLite数据库的方法,对于Python的学习有不错的参考借鉴价值.分享给大家供大家参考之用.具体方法如下: 实例代码如下: ? 1 2 3 4 5 6 7 8 ...

  9. iOS开发之iOS程序偏好设置(Settings Bundle)的使用

    目录[-] 1.添加设置项 2.设置的控件 3.编辑设置项的文件 4.在程序中获取Settings 和写入Settings 添加UI 5.实现读取设置和保存代码 在Android手机上, 在某个程序里 ...

  10. iOS -一些常用的方法

    1.获取本地的语言 + (NSString *)getLocalLanguage { NSString *language = [[[NSUserDefaults standardUserDefaul ...