noip 2012 疫情控制
/*
考试的时候没想出正解 也没打暴力 时间不够了
随便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 疫情控制的更多相关文章
- 【NOIP 2012 疫情控制】***
题目描述 H 国有 n 个城市,这 n 个城市用 n-1 条双向道路相互连通构成一棵树,1 号城市是首都, 也是树中的根节点. H 国的首都爆发了一种危害性极高的传染病.当局为了控制疫情,不让疫情扩散 ...
- NOIP 2012 疫情控制(二分+贪心+倍增)
题解 二分时间 然后一个显然的事是一个军队向上爬的越高它控制的点越多 所以首先军队尽量往上爬. 当一个军队可以爬到根节点我们记录下它的剩余时间T和它到达根结点时经过的根节点的子节点son. 当一个军队 ...
- 基础算法(二分,贪心):NOIP 2012 疫情控制
题目大意 给出一棵n个节点的树,根是1,要在除根节点以外的点建立检查点,使得从每条根到叶子的路径上都至少存在一个检查点.检查点由军队来建立.初始军队的位置是给定的,移动军队走一条边需要花费这条边的权值 ...
- 【NOIP】提高组2012 疫情控制
[题意]n个点的树,1为根,要求删除一些点使得截断根节点和所有叶子结点的路径(不能删根,可以删叶子).有m支军队在m个点上,每时刻所有军队可以走一步,最终走到的地方就是删除的点,求最短时间. [算法] ...
- Codevs 1218 疫情控制 2012年NOIP全国联赛提高组
1218 疫情控制 2012年NOIP全国联赛提高组 时间限制: 2 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description H 国有 n 个城市,这 ...
- 疫情控制 2012年NOIP全国联赛提高组(二分答案+贪心)
P1084 疫情控制 题目描述 H 国有 n 个城市,这 n 个城市用 n-1 条双向道路相互连通构成一棵树,1 号城市是首都,也是树中的根节点. H 国的首都爆发了一种危害性极高的传染病.当局为了控 ...
- [NOIP2012] 提高组 洛谷P1084 疫情控制
题目描述 H 国有 n 个城市,这 n 个城市用 n-1 条双向道路相互连通构成一棵树,1 号城市是首都, 也是树中的根节点. H 国的首都爆发了一种危害性极高的传染病.当局为了控制疫情,不让疫情扩散 ...
- [NOIP2012] day2 T3疫情控制
题目描述 H 国有 n 个城市,这 n 个城市用 n-1 条双向道路相互连通构成一棵树,1 号城市是首都,也是树中的根节点. H 国的首都爆发了一种危害性极高的传染病.当局为了控制疫情,不让疫情扩散到 ...
- 洛谷P1084 [NOIP2012提高组Day2T3]疫情控制
P1084 疫情控制 题目描述 H 国有 n 个城市,这 n 个城市用 n-1 条双向道路相互连通构成一棵树,1 号城市是首都,也是树中的根节点. H 国的首都爆发了一种危害性极高的传染病.当局为了控 ...
随机推荐
- uboot移植参考资料
参考文档:移植u-boot-1.1.6到TQ2440文档.pdf 参考网页:uboot在S3C2440上移植<出自超哥(相广超)>
- 计算广义积分$$\int_0^{+\infty}\cos x^p {\rm d}x,\int_0^{+\infty}\sin x^p {\rm d}x, p>1$$
${\bf 解:}$ 在角状域$G=\{z\in\mathbb{C}|0<{\rm Arg}z<\frac{\pi}{2p}\}$上引入辅助函数$e^{iz^p}$, 其中$z^p=|z| ...
- JAVA存取对象属性时,如果开程多线程,记得对相关存取方法作原子化操作定义
最显著的应用当然是银行存款和取款,不要存在存取数字和实际发生不一样的情况. synchronized关键字. class BankAccount { private int balance = 100 ...
- java的"=="与"equals"
equals 方法是 java.lang.Object 类的方法. 有两种用法说明: (1)对于字符串变量来说,使用“==”和“equals()”方法比较字符串时,其比较方法不同. “==”比较两个变 ...
- POJ 1651 Multiplication PuzzleDP方法:
有N张写有数字的卡片排成一行,按一定次序从中拿走N-2张(第1张和最后一张不能拿),每次只拿一张,取走一张卡片的同时,会得到一个分数,分值的计算方法是:要拿的卡片,和它左右两边的卡片,这三张卡片上数字 ...
- C#调用Exe文件的方法及如何判断程序调用的exe已结束
很简单的代码就可以实现C#调用EXE文件,如下: 引入using System.Diagnostics; 调用代码: Process.Start(exe文件名); 或直接 System.Diagnos ...
- [Theano] Theano初探
1. Theano用来干嘛的? Theano was written at the LISA lab to support rapid development of efficient machine ...
- 双有序队列算法——处理哈夫曼K叉树的高效算法
算法介绍: 哈夫曼树的思路及实现众所周知,大部分是用堆来维护和实现,这种思路比较清晰,在K比较小的时候处理较快(具体例子接下来再说),而且编程复杂度不是很高,利于应用.但是,其所用的数据结构是树,是在 ...
- Krypton Factor 困难的串-Uva 129(回溯)
原题:https://uva.onlinejudge.org/external/1/129.pdf 按照字典顺序生成第n个“困难的串” “困难的串”指的是形如ABAB, ABCABC, CDFGZEF ...
- SRM 398(1-250pt)
题意:有两个变量x和y,三种运算符+,*,-,组成等式"变量 运算符 变量 运算符 变量 运算符 变量",要求每个变量恰好出现两次,且等式的值为val的等式有多少个.注意不计算运算 ...