题目大意

  给出一棵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. 线程池读取List<T>实例

    private static readonly Object ThisLock = new object(); private static readonly AutoResetEvent AutoR ...

  2. 反射 介绍System.Type类

    本节先介绍system.Type类,通过这个类可以访问关于任何数据类型的信息. 1. system.Type类以前把Type看作一个类,但它实际上是一个抽象的基类.只要实例化了一个Type对象,实际上 ...

  3. MongoDB源码分析——mongo主程序入口分析

    Edit   源码版本为MongoDB 2.6分支 mongo主程序入口分析 mongo是MongoDB提供的一个执行JavaScript脚本的客户端工具,可以用来和服务端交互,2.6版本的Mongo ...

  4. Android清空画布

    public void clear() { Paint paint = new Paint(); paint.setXfermode(new PorterDuffXfermode(Mode.CLEAR ...

  5. v4l2简介

    V4L是linux内核中关于视频设备的子系统,为linux下的视频驱动提供了统一的接口,使应用程序可以使用统一的API操作不同的视频设备,简化视频系统的开发与维护 V4L2相比与V4L有更好的扩展性和 ...

  6. 网站开发常用jQuery插件总结(六)关键词说明插件cluetip

    我们开发的网站,总有它一定的用途.如企业站用来宣传企业或展示产品,技术站用来分享自己的思路和经验.既然网站有了它的用途,那么就拥有了它本身的关键词(关键词说明网站的主要内容).例如企业站的关键词大部分 ...

  7. 为 DataGridView 控件添加行号

    虽然好像不经常用到,不过还是记下来防止以后用到 /// <summary> /// 为 DataGridView 控件添加行号 /// </summary> /// <p ...

  8. document.getElementById获取不到标签值

    var apliay=document.getElementById('apliay_ok'); 代码里指定有id="apliay_ok"的标签,但是获取不到,折腾半天原来是因为在 ...

  9. Hadoop中的RPC

    基于hadoop2.6.4,RPC相关的实现位于hadoop-common这个project中hadoop-common-project/hadoop-common/src/main/java的包pa ...

  10. Leaflet学习笔记-Leaflet.awesome-markers

    基础篇传送门 http://www.cnblogs.com/CoffeeEddy/p/4919987.html 效果图 是不是感觉很美观啊 为什么选择awesome 地图上面需要各种各样的Mark,难 ...