/*
考试的时候没想出正解 也没打暴力 时间不够了
随便yy了几种情况按出现的先后顺序处理而没有贪心
的了20分 不粘了
正解是围绕首都的儿子来搞的
显然先二分答案 对于每个限定的最大时间
我们尝试着那每个军队向根节点蹦 能蹦到的记下来最靠近根的点 并记下剩下多少时间
不能蹦到的 记下能蹦到哪里 并且标记为已有军队
最后updata一下不能蹦到的 说不定可以蹦到首都的儿子 或者首都的儿子的儿子都能蹦到
这里自己脑补一下图吧 很好理解的
然后我们就有了一些需要军队驻扎的首都的儿子还有到能到首都的军队及剩下的时间
然后开始分配 这里我们贪心的来搞
枚举还能移动的军队 首先看看他来的那个儿子是否需要军队 如果需要就过去
否则的话移动到它刚刚能到的最近的
最后统计一下是不是所有的需要军队的首都的儿子都有军队了 */
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 50010
using namespace std;
int n,m,num,head[maxn],fa[maxn][],dis[maxn][],f[maxn],ans=-;
int p[maxn],sc,sg;
struct Children
{
int t,c;
}cl[maxn];
struct Get
{
int d,fr;
}get[maxn];
struct node
{
int v,t,pre;
}e[maxn*];
int cmp1(const Children &x,const Children &y)
{
return x.t<y.t;
}
int cmp2(const Get &x,const Get &y)
{
return x.d<y.d;
}
void Clear()
{
memset(f,,sizeof(f));
sc=sg=;
}
void Add(int from,int to,int dis)
{
num++;e[num].v=to;
e[num].t=dis;
e[num].pre=head[from];
head[from]=num;
}
void init()
{
scanf("%d",&n);
int x,y,z;
for(int i=;i<=n-;i++)
{
scanf("%d%d%d",&x,&y,&z);
Add(x,y,z);Add(y,x,z);
}
}
void Dfs(int now,int from,int len)
{
fa[now][]=from;dis[now][]=len;
for(int i=head[now];i;i=e[i].pre)
if(e[i].v!=from)
Dfs(e[i].v,now,e[i].t);
}
void Get_fa()
{
for(int j=;j<=;j++)
for(int i=;i<=n;i++)
{
fa[i][j]=fa[fa[i][j-]][j-];
dis[i][j]=dis[i][j-]+dis[fa[i][j-]][j-];
}
}
void Up(int now,int from)
{
int falg=,isleaf=;
for(int i=head[now];i;i=e[i].pre)
if(e[i].v!=from)
{
isleaf=;Up(e[i].v,now);
if(f[e[i].v]==)falg=;
}
if(!falg&&!isleaf)f[now]=;
}
bool Judge(int x)
{
Clear();
for(int k=;k<=m;k++)
{
int sum=,a=p[k];
for(int i=;i>=;i--)
if(fa[a][i]&&sum+dis[a][i]<=x)
{
sum+=dis[a][i];
a=fa[a][i];
}
if(a!=)f[a]=;
else
{
cl[++sc].t=x-sum;a=p[k];
for(int i=;i>=;i--)
if(fa[a][i]>)a=fa[a][i];
cl[sc].c=a;
}
}
Up(,);
for(int i=head[];i;i=e[i].pre)
if(f[e[i].v]==)
{
get[++sg].fr=e[i].v;
get[sg].d=e[i].t;
}
sort(cl+,cl++sc,cmp1);
sort(get+,get++sg,cmp2);
int pi=;
for(int i=;i<=sc;i++)
{
while(f[get[pi].fr])pi++;
if(f[cl[i].c]==)
{
f[cl[i].c]=;
continue;
}
if(cl[i].t>=get[pi].d)
{
f[get[pi].fr]=;
pi++;
}
}
for(int i=;i<=sg;i++)
if(f[get[i].fr]==)return ;
return ; }
void slove()
{
scanf("%d",&m);
for(int i=;i<=m;i++)
scanf("%d",&p[i]);
int l=,r=0x3f3f3f3f;
while(l<=r)
{
int mid=(l+r)/;
if(Judge(mid))
{
r=mid-;ans=mid;
}
else l=mid+;
}
printf("%d\n",ans);
}
int main()
{
//freopen("blockade.in","r",stdin);
//freopen("blockade.out","w",stdout);
init();
Dfs(,,);
Get_fa();
slove();
return ;
}

noip 2012 疫情控制的更多相关文章

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

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

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

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

  3. 基础算法(二分,贪心):NOIP 2012 疫情控制

    题目大意 给出一棵n个节点的树,根是1,要在除根节点以外的点建立检查点,使得从每条根到叶子的路径上都至少存在一个检查点.检查点由军队来建立.初始军队的位置是给定的,移动军队走一条边需要花费这条边的权值 ...

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

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

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

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

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

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

  7. [NOIP2012] 提高组 洛谷P1084 疫情控制

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

  8. [NOIP2012] day2 T3疫情控制

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

  9. 洛谷P1084 [NOIP2012提高组Day2T3]疫情控制

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

随机推荐

  1. Git error- fatal- Needed a single revision

    最近在开发中由于项目结构的重构,有一部分代码被抽出来作为了公共库(git submodule),这样公共库可以独立维护,同时其他库调用它也是非常方便的,避免了到处复制代码的痛苦. 但我在项目重构后第一 ...

  2. Vim及VimScript资料总结《转载》

    版权声明:本文为博主原创文章,未经博主允许不得转载.   目录(?)[+]   Vim教程 入门 Vim 实用技术 Learning the vi and Vim Editors A Byte of ...

  3. 安卓SDK Manager自动管理各种包

    安卓ADT不能自动从google下载sdk等各种工具 修改hosts文件下载成功 210.242.125.89  dl-ssl.google.com 210.242.125.89  dl.google ...

  4. 用链表解决if语句过多的问题(C/C++实现)

    起因 http://www.cnblogs.com/code-style/p/3499408.html 设计模式的解决方案(基于python语言) http://www.cnblogs.com/cod ...

  5. linux中硬盘及网卡的表示方法

    Linux中的所有设备均表示为/dev下的一个文件,各种IDE设备分配一个由hd前缀组成的文件:而对于各种SCSI设备,则分配了一个由sd前缀组成的文件,例如: IDE0接口上的主盘成为/dev/hd ...

  6. 转:PHP非阻塞模式

    你可以任意转摘“PHP非阻塞模式”,但请保留本文出处和版权信息.作者:尘缘,QQ:130775,来源:http://www.4wei.cn/archives/1002336 让PHP不再阻塞当PHP作 ...

  7. 通用GPIO模拟串口,提供源代码,本人经过测试OK(第一版)

    --------------------------serial.h------------------------------------------ #ifndef _SERIAL_H_ #def ...

  8. 【POJ】1204 Word Puzzles

    这道题目各种wa.首先是错了一个坐标,居然没测出来.然后是剪枝错误.搜索pen时就返回,可能还存在串pen*. #include <cstdio> #include <cstring ...

  9. SDUT 最短路径(二维SPFA)

    http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=2622 #include<stdio.h& ...

  10. code_analyzer(代码分析助手)

    软件名: code_analyzer 使用c语言 pcre正则库分析源码文件,包括文件中的头文件.宏定义.函数. 用途: 无聊时,可以用来打发下时间. 演示: 对于本源程序的分析结果如下: ##### ...