题目大意

  给出一棵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. DailyNote

    删除node-modules文件夹 npm install -g rimraf rimraf node_modules 绘制一条贝塞尔曲线: context.quadraticCurveTo(x1,y ...

  2. js 无刷新分页代码

    /** * 分页事件处理 */function paging(){ $("#firstPage").click(function(){ //首页 var pageNo = getP ...

  3. Nginx的反向代理

    先通过简单的图来说明一下正向代理和反向代理吧~ 正向代理 代理其实就是一个中介,A和B本来可以直连,中间插入一个C,C就是中介.刚开始的时候,代理多数是帮助内网client访问外网server用的(比 ...

  4. Linux下Docker安装

    1 在 CentOS 6.4 上安装 docker   docker当前官方只支持Ubuntu,所以在 CentOS 安装Docker比较麻烦(Issue #172).   docker官方文档说要求 ...

  5. Ubuntu 之旅—— 调整扩展屏分辨率

    打开终端输入 xrandr 得到如下信息 Screen 0: minimum 320 x 200, current 2390 x 768, maximum 8192 x 8192 LVDS conne ...

  6. JS将搜索的关键字高亮显示实现代码

    这篇文章介绍了JS将搜索的关键字高亮显示实现代码,有需要的朋友可以参考一下 用JS让文章内容指定的关键字加亮 是这样的.. 现在有这些关键字:美容,生活,购物 当在文章里头出现这些关键字,就把它加亮显 ...

  7. PHP面向对象的特性

    1.抽象性2.封装性3.继承extends4.多态

  8. Config IIS server6.0-- HTTP 错误 500.21 - Internal Server Error 解决方案

    HTTP 错误 500.21 - Internal Server Error 解决方案         不久前重新安装了Windows7,在安装了VS2010 开发平台之后,将网站发布到IIS,访问发 ...

  9. Python里隐藏的 " 诗 "

    在 Python 的Lib目录里有一个:this.Py (或者在交互式解释器中输入import this) 它其实是隐藏的一首诗 The Zen of Python, by Tim Peters &l ...

  10. 解决cocos2d 热更是连不上https服务器

    最近苹果宣布所有上架应用都要用https,我们后端走的是同一个函数,导致Android也要连接https. 百度了下,网上说客户端不需要做什么特殊处理,因为cocos本身是支持https的.但是服务端 ...