题目大意

  给出一棵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. Object-C在Nil上调用方法

    在Object-C中,nil对象的作用等同于很多其它语言的NULL指针.不同的地方在于,在nil上调用方法不会导致程序崩溃或抛出异常. 这种技术被用在很多地方,但是对于我们来讲,最主要的就是我们不用在 ...

  2. C语言链表全操作(增,删,改,查,逆序,递增排序,递减排序,链式队列,链式栈)

    一,数据结构——链表全操作: 链表形式: 其中,每个节点(Node)是一个结构体,这个结构体包含数据域,指针域,数据域用来存放数据,指针域则用来指向下一个节点: 特别说明:对于单链表,每个节点(Nod ...

  3. Universal Naming Convention (UNC)

    Quote from: http://compnetworking.about.com/od/windowsnetworking/g/unc-name.htm Definition: UNC is a ...

  4. 访问Access数据库(有多个数据库时 体现多态)

    如果想编写单机版MIS.小型网站等对数据库性能要求不高的系统,又不想安装SQLServer,可以使用Access(MDAC),只要一个mdb文件就可以了.使用Access创建mdb文件,建表.OleD ...

  5. 菜鸟的MySQL学习笔记(二)

    3-1约束: 1.约束保证数据的完整性和一致性: 2.约束分表级约束(两个或两个个以上字段的约束)和列级约束(一个字段约束): 3.NOT NULL       非空: PRIMARY KEY     ...

  6. <汇编语言系列>计算机硬件系统与汇编

    寒假时,有幸拜读了卡内基-梅隆大学(CMU)的Randal E.Bryant 和 David R.O'Hallaron的名著——深入理解计算机系统(Computer System: A Program ...

  7. jQuery学习 day01

    最近受某大牛指点(我不会说他姓范),了解了一下jQuery,据说很牛X,就了解了一下,第一天,分享给大家一些心得吧. 1.首先就是导入jQuery文件了,这里我是去jQuery官网下载的.(大家可以去 ...

  8. Winform动态加载TabControl用法

    private void BindTabData() { dtIPD = new DataTable(); //drItem = new DataTable(); //获取[项目大类]列表显示于 Ta ...

  9. C# Linq To DataTable 分组统计 DEMO

    DataTable dt = SQLLayer.Get工作量统计(beginDate, endDate);             var querySum = from t in dt.AsEnum ...

  10. css reset浅谈

    我们都知道,web开发中浏览器兼容性是困扰很多开发者的一个问题.所谓兼容性问题,即不同浏览器对同一段代码有不同的解析效果.而我们的需求往往是无论用户使用何种浏览器查看我们的网站,都应该获得相同或相近的 ...