疫情控制 blockad

题目描述

H 国有 n 个城市,这 n 个城市用 n-1 条双向道路相互连通构成一棵树, 1 号城市是首都, 也是树中的根节点。

H 国的首都爆发了一种危害性极高的传染病。当局为了控制疫情,不让疫情扩散到边境 城市(叶子节点所表示的城市),决定动用军队在一些城市建立检查点,使得从首都到边境 城市的每一条路径上都至少有一个检查点,边境城市也可以建立检查点。但特别要注意的是, 首都是不能建立检查点的。 现在,在 H 国的一些城市中已经驻扎有军队,且一个城市可以驻扎多个军队。一支军队可以在有道路连接的城市间移动,并在除首都以外的任意一个城市建立检查点,且只能在 一个城市建立检查点。一支军队经过一条道路从一个城市移动到另一个城市所需要的时间等 于道路的长度(单位:小时)。

请问最少需要多少个小时才能控制疫情。注意:不同的军队可以同时移动。

输入

第一行一个整数 n,表示城市个数。

接下来的 n-1 行,每行 3 个整数,u、v、w,每两个整数之间用一个空格隔开,表示从 城市 u 到城市 v 有一条长为 w 的道路。数据保证输入的是一棵树,且根节点编号为 1。

接下来一行一个整数 m,表示军队个数。

接下来一行 m 个整数,每两个整数之间用一个空格隔开,分别表示这 m 个军队所驻扎 的城市的编号。

输出

共一行,包含一个整数,表示控制疫情所需要的最少时间。如果无法控制疫情则输出-1。

样例输入

4
1 2 1
1 3 2
3 4 3
2
2 2

样例输出

3

提示

【样例解释】

第一支军队在 2 号点设立检查点,第二支军队从 2 号点移动到 3 号点设立检查点,所需 时间为 3 个小时

【数据范围】

保证军队不会驻扎在首都。

对于 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

来源

NOIP2012提高组Day2


solution

容易发现答案具有单调性。

二分答案,然后尝试构造最优方案。

我们应该让所有点尽可能往上跳,如果步数充裕还可以去到别的子树去驻扎。

可以用倍增的方法算出每个点会跳到哪里,如果能跳到根就记下还能走几步。

那么跳不到根的,他的贡献是确定的,所以可以先确定根的那些儿子是已被处理好了。

然后我们把剩余的点按剩余步数排序。记剩余步数为res

如果一个点跳不回自己来的儿子,并且这个儿子还没处理好,那就让他跳回去。

因为让另一个res>它的点去肯定不优。

接下来就对每一个还未被占领的儿子按占领代价(也就是根到它的长度)排序。

贪心匹配即可。

总结:先找性质,二分完构造最优解。细节需想清楚。

 #include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#define maxn 50004
#define ll long long
using namespace std;
int n,m,head[maxn],tot,f[maxn][],be[maxn];
int match[maxn],top;
ll l[maxn][],len[maxn];
bool flag[maxn];
struct node{
int v,nex,w;
}e[maxn*];
struct no{
int st,ed;
ll res;
}s[maxn];
void lj(int t1,int t2,int t3){
e[++tot].v=t2;e[tot].w=t3;e[tot].nex=head[t1];head[t1]=tot;
}
void dfs(int k,int fa){
f[k][]=fa;
if(fa==)be[k]=k;
else be[k]=be[fa];
for(int i=head[k];i;i=e[i].nex){
if(e[i].v!=fa){
l[e[i].v][]=e[i].w;
dfs(e[i].v,k);
}
}
}
void work(int k){
bool F=,fl=;
for(int i=head[k];i;i=e[i].nex){
if(e[i].v==f[k][])continue;
work(e[i].v);
if(!fl)fl=,F=;
F&=flag[e[i].v];
}
flag[k]|=F;
}
bool Mr(no a,no b){
return a.res<b.res;
}
bool cmp(int a,int b){
return len[a]<len[b];
}
bool pd(ll mid){ for(int i=;i<=n;i++)flag[i]=;
for(int i=;i<=m;i++){
int k=s[i].st;ll la=mid;
for(int x=;x>=;x--){
if(f[k][x]&&l[k][x]<=la){
la-=l[k][x],k=f[k][x];
}
}
s[i].ed=k;s[i].res=la;
if(k>)flag[k]=;
}
work();
sort(s+,s+m+,Mr);
for(int i=;i<=m;i++){
if(s[i].ed!=||flag[be[s[i].st]])continue;
int b=be[s[i].st];
if(s[i].res<len[b])flag[b]=,s[i].ed=b;
}
top=;
for(int i=head[];i;i=e[i].nex){
if(flag[e[i].v])continue;
match[++top]=e[i].v;
}
sort(match+,match+top+,cmp);
int j=;
for(int i=;i<=top;i++){ int L=len[match[i]];
while((s[j].ed!=||s[j].res<L)&&j<=m)j++;
j++;
if(j>m+)return ;
}
return ;
}
int main(){
cin>>n;
for(int i=,t1,t2,t3;i<n;i++){
scanf("%d%d%d",&t1,&t2,&t3);
lj(t1,t2,t3);lj(t2,t1,t3);
}
dfs(,);
for(int i=head[];i;i=e[i].nex)len[e[i].v]=e[i].w;
for(int j=;j<=;j++)
for(int i=;i<=n;i++){
f[i][j]=f[f[i][j-]][j-];
l[i][j]=l[i][j-]+l[f[i][j-]][j-];
}
cin>>m;
for(int i=;i<=m;i++)scanf("%d",&s[i].st);
ll l=,r=1e16;
while(l<r){
ll mid=l+r>>;
if(pd(mid))r=mid;
else l=mid+;
}
if(l==1e16)puts("-1");
else cout<<l<<endl;
return ;
}

疫情控制 blockade的更多相关文章

  1. codevs1218 疫情控制

    疫情控制(blockade.cpp/c/pas)[问题描述]H 国有 n 个城市,这 n 个城市用 n-1 条双向道路相互连通构成一棵树,1 号城市是首都,也是树中的根节点.H 国的首都爆发了一种危害 ...

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

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

  3. 【NOIP2012】 疫情控制

    [NOIP2012] 疫情控制 标签: 倍增 贪心 二分答案 NOIP Description H 国有 n 个城市,这 n 个城市用 n-1 条双向道路相互连通构成一棵树, 1 号城市是首都, 也是 ...

  4. Luogu 1084 NOIP2012 疫情控制 (二分,贪心,倍增)

    Luogu 1084 NOIP2012 疫情控制 (二分,贪心,倍增) Description H 国有 n 个城市,这 n 个城市用 n-1 条双向道路相互连通构成一棵树, 1 号城市是首都, 也是 ...

  5. [NOIP2012]疫情控制 贪心 二分

    题面:[NOIP2012]疫情控制 题解: 大体思路很好想,但是有个细节很难想QAQ 首先要求最大时间最小,这种一般都是二分,于是我们二分一个时间,得到一个log. 然后发现一个军队,越往上走肯定可以 ...

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

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

  7. CH6301 疫情控制

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

  8. luoguP1084 疫情控制(题解)(搜索+贪心)

    luoguP1084 疫情控制 题目 #include<iostream> #include<cstdlib> #include<cstdio> #include& ...

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

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

随机推荐

  1. 【模板时间】◆模板·III◆ 单调子序列

    ◆模板·III◆ 单调子序列 以前只知道DP用 O(n2) 的做法,现在才发现求单调子序列方法好多…… ◇ 模板简述 单调子序列包括 升序/降序/非升序/非降序 子序列.主要题型如下: ①在原串中找到 ...

  2. spring-mybatis整合异常2

    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' ...

  3. 解决.NET Core R1中文乱码问题

    今天写了一个简单的.NET Core RC1控制台程序,发现中文显示一直是乱码.查看操作系统设置,没有问题:查看源文件编码,也没有问题:甚至查看了Console字符编码相关的注册表,依然没有发现问题. ...

  4. 10.2 DOM 操作技术【JavaScript高级程序设计第三版】

    很多时候,DOM 操作都比较简明,因此用JavaScript 生成那些通常原本是用HTML 代码生成的内容并不麻烦.不过,也有一些时候,操作DOM 并不像表面上看起来那么简单.由于浏览器中充斥着隐藏的 ...

  5. python学习之变量类型

    变量: 变量是保存在内存中的值,根据变量类型开辟不同的内存空间且只允许符合该数据类型的数据才可以被存储在该内存空间中 变量赋值: 在Python中定义变量时,无需像其他语言一样需要声明数据类型.每个变 ...

  6. 虚拟机linux桥接联网问题

    Linux系统为redhat5.8 虚拟机的版本:vm8.0 本人刚刚开始接触linux,今日需要通过linux进行联网,因此也学习了一点点关于虚拟机的联网的知识,在此与大家进行分享,希望大家可以之处 ...

  7. 15 Django组件-中间件

    中间件 中间件的概念 中间件顾名思义,是介于request与response处理之间的一道处理过程,相对比较轻量级,并且在全局上改变django的输入与输出.因为改变的是全局,所以需要谨慎实用,用不好 ...

  8. SpringMVC---四大注解

    SpringMVC四大注解 Component 通用标注,在不清楚使用哪个注解的时候,可以使用Component通用注解 Controller 标注web请求控制器 Service 标注Service ...

  9. Docker容器 - 容器时间跟宿主机时间同步

    在Docker容器创建好之后,可能会发现容器时间跟宿主机时间不一致,这就需要同步它们的时间,让容器时间跟宿主机时间保持一致. 转载自:https://www.cnblogs.com/kevingrac ...

  10. CC3200串口UART1配置

    1. 首先打开工程\CC3200SDK_1.1.0\example\adc\ewarm,以ADC例程为例,修改串口引脚复用,先看下引脚图 2. 修改引脚复用代码 void PinMuxConfig(v ...