疫情控制 blockade
疫情控制 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。
来源
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的更多相关文章
- codevs1218 疫情控制
疫情控制(blockade.cpp/c/pas)[问题描述]H 国有 n 个城市,这 n 个城市用 n-1 条双向道路相互连通构成一棵树,1 号城市是首都,也是树中的根节点.H 国的首都爆发了一种危害 ...
- Codevs 1218 疫情控制 2012年NOIP全国联赛提高组
1218 疫情控制 2012年NOIP全国联赛提高组 时间限制: 2 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description H 国有 n 个城市,这 ...
- 【NOIP2012】 疫情控制
[NOIP2012] 疫情控制 标签: 倍增 贪心 二分答案 NOIP Description H 国有 n 个城市,这 n 个城市用 n-1 条双向道路相互连通构成一棵树, 1 号城市是首都, 也是 ...
- Luogu 1084 NOIP2012 疫情控制 (二分,贪心,倍增)
Luogu 1084 NOIP2012 疫情控制 (二分,贪心,倍增) Description H 国有 n 个城市,这 n 个城市用 n-1 条双向道路相互连通构成一棵树, 1 号城市是首都, 也是 ...
- [NOIP2012]疫情控制 贪心 二分
题面:[NOIP2012]疫情控制 题解: 大体思路很好想,但是有个细节很难想QAQ 首先要求最大时间最小,这种一般都是二分,于是我们二分一个时间,得到一个log. 然后发现一个军队,越往上走肯定可以 ...
- 疫情控制 2012年NOIP全国联赛提高组(二分答案+贪心)
P1084 疫情控制 题目描述 H 国有 n 个城市,这 n 个城市用 n-1 条双向道路相互连通构成一棵树,1 号城市是首都,也是树中的根节点. H 国的首都爆发了一种危害性极高的传染病.当局为了控 ...
- CH6301 疫情控制
6301 疫情控制 0x60「图论」例题 描述 H国有 n 个城市,这 n 个城市用 n-1 条双向道路相互连通构成一棵树,1号城市是首都,也是树中的根节点. H国的首都爆发了一种危害性极高的传染病. ...
- luoguP1084 疫情控制(题解)(搜索+贪心)
luoguP1084 疫情控制 题目 #include<iostream> #include<cstdlib> #include<cstdio> #include& ...
- 洛谷P1084 [NOIP2012提高组Day2T3]疫情控制
P1084 疫情控制 题目描述 H 国有 n 个城市,这 n 个城市用 n-1 条双向道路相互连通构成一棵树,1 号城市是首都,也是树中的根节点. H 国的首都爆发了一种危害性极高的传染病.当局为了控 ...
随机推荐
- Percona-Tookit工具包之pt-mext
Preface We are always obliged to analyze many outputs generated by various tools directly ev ...
- mysql 命令 小结
CREATE DATABASE IF NOT EXISTS yourdbname DEFAULT CHARSET utf8 COLLATE utf8_general_ci;创建中文数据库show gl ...
- http协议组成(请求状态码)
http请求由:请求行:消息报头:请求正文组成 //请求行 Request URL: http://172.32.4.33:8080/operation/v2/autoServer/queryAuto ...
- Java基础——对象和类
将包含main方法的类称为主类. 变量的作用域是指变量可以在程序中引用的范围. 实例变量和静态变量的作用域是整个类,无论变量是在哪里声明的. 局部变量的声明和使用都在一个方法的内部. 一个类的实例变量 ...
- 使用Windows Live Writer写文章时不要用360清除垃圾
ref:http://www.zhengsiwei.com/write-an-article-to-use-windows-live-writer-dont-use-360-to-remove-rub ...
- js简单的获取与输出
js获取标签内容和输出内容到页面 获取: html: <select id="choiceSelect" onchange="changeImg()"&g ...
- PHP.33-TP框架商城应用实例-后台9-商品相册-修改、删除(AJAX)
商品相册图片删除 当商品删除时,把相册中的图片一并从硬盘和数据库中删除,根据商品id[因为每一张商品相片都会生成三张缩略图,所以删除时要将其缩略图一并删除] //钩子方法_before_delete: ...
- Linux 安装github并配置ssh
首先,你得有个github帐号. 1.用apt-get install git的方式安装git test@er:/$ sudo add-apt-repository ppa:git-core/ppa ...
- 线性表(List)
1.什么是线性表(List)? 零个或多个数据元素的有限序列. (1)元素之间是有序的. (2)线性表强调是有限的. 2.线性表有哪些操作? (1)线性表的创建和初始化,InitList (2)判空, ...
- WPF and Silverlight.ComboBox 如何通过 Binding IsDropDownOpen 实现下拉菜单展开
In the WPF example the Popup and the ToggleButton (the arrow on the right) are bound with the proper ...