题目描述

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

H 国的首都爆发了一种危害性极高的传染病。当局为了控制疫情,不让疫情扩散到边境城市(叶子节点所表示的城市),决定动用军队在一些城市建立检查点,使得从首都到边境城市的每一条路径上都至少有一个检查点,边境城市也可以建立检查点。但特别要注意的是,首都是不能建立检查点的。

现在,在 H 国的一些城市中已经驻扎有军队,且一个城市可以驻扎多个军队。一支军队可以在有道路连接的城市间移动,并在除首都以外的任意一个城市建立检查点,且只能在一个城市建立检查点。一支军队经过一条道路从一个城市移动到另一个城市所需要的时间等于道路的长度(单位:小时)。

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

输入输出格式

输入格式:

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

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

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

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

输出格式:

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

输入输出样例

输入样例#1:

4
1 2 1
1 3 2
3 4 3
2
2 2
输出样例#1:

3

说明

【输入输出样例说明】

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

【数据范围】

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

对于 20%的数据,2≤ n≤ 10;

对于 40%的数据,2 ≤n≤50,0<w <10^5;

对于 60%的数据,2 ≤ n≤1000,0<w <10^6;

对于 80%的数据,2 ≤ n≤10,000;

对于 100%的数据,2≤m≤n≤50,000,0<w <10^9。

这是一棵树,我们可以很容易发现对于一支军队把他往树根走是不影响他本身已经能够封锁的子树的

另外我们还可以发现 对于一支军队越接近树根越好,因为这样他能封锁的子树可以尽可能的多

我们还可以发现 对于还没有封锁的子树,我们必须外调可以调过来的军队来封锁。

假设时间无现长 且军队足够多的情况下肯定能控制疫情。

这是一个可行性的方案 时间可以二分

如何知道哪些军队可以外调?

我们可以发现如果一个军队到了首都 还有时间可以继续走,那就说明可以外调。

到这里就有一个很明显的贪心分配的方法了:

让还剩时间多的军队走尽可能长的路

特别的,如果一个军队到了首都后 他原本封锁的子树不安全了(没有军队了),且自己还剩下的时间不能再走回去那么就让他退一步。

如何把军队往上推到首都?

一步一步显然过慢了

由于路径是确定的,跟开车旅行一样,倍增即可。

于是问题就可以解决了。

二分时间,判断在这个时间里能不能控制疫情,用倍增把军队往首都那推,然后把那些剩余时间不够回去原来子树的军队退回去,然后剩下的军队贪心分配就可以了。

至于不能控制疫情的情况,就是军队数小于根孩子个数,然而数据似乎并没有这个数据(于是乎我也没判了2333)

 #include <cstring>
#include <cstdio>
#include <iostream>
#include <algorithm>
#define N 100005
using namespace std;
struct data{
long long di;
int loc;
}em[N/],li[N/],cap[N/];
int num,n,m,next[N],to[N],head[N/],fa[N],from[N/],ca,lis,f[N/][],list[N/];
long long l,r,ti,up[N/][],ans,dis[N/],power[N],w,sign[N/],visit[N/],unsafe[N/];
void add(int u,int v,long long w){
num++;
next[num]=head[u];
to[num]=v;
power[num]=w;
head[u]=num;
num++;
next[num]=head[v];
to[num]=u;
power[num]=w;
head[v]=num;
}
void DFS(int x){
for (int v,i=head[x];i;i=next[i]){
v=to[i];
if (!visit[v]&&(fa[x]!=v||x==)){
visit[v]=;
fa[v]=x;
dis[v]=dis[x]+power[i];
ti=ti<dis[v]?dis[v]:ti;
DFS(v);
}
}
}
void pre(){
for (int i=;i<=n;++i){
f[i][]=fa[i];
up[i][]=dis[i]-dis[fa[i]];
}
for (int j=;j<=;++j)
for (int i=;i<=n;++i){
f[i][j]=f[f[i][j-]][j-];
up[i][j]=dis[i]-dis[f[i][j]];
}
}
bool cmp1(const struct data a,const struct data b){
return (a.di>b.di);
}
bool cmp3(int a,int b){
return (a>b);
}
void updata(int x,long long ti){
int pos=li[x].loc;
long long qwq=ti;
for (int i=;i>=;--i)
if (up[pos][i]<=ti&&f[pos][i]!=&&f[pos][i]!=){
ti-=up[pos][i];
pos=f[pos][i];
}
if (fa[pos]==&&ti>=up[pos][])
from[x]=pos,cap[++ca].loc=x,cap[ca].di=ti-up[pos][];
else sign[pos]=qwq;
}
void check(int x,long long ti,int son){
int qwq=;
for (int i=head[x],v;i;i=next[i]){
v=to[i];
qwq++;
if (v==fa[x]) continue;
if (sign[v]==ti) continue;
if (x==) check(v,ti,v);
else check(v,ti,son);
}
if (qwq==) visit[son]=ti;
}
bool work(long long ti){
lis=ca=;
for (int i=;i<=m;++i)
li[i]=em[i];
for (int i=m;i>=;--i)
updata(i,ti);
check(,ti,);
for (int i=head[];i;i=next[i])
if (visit[to[i]]==ti) unsafe[to[i]]=ti;
for (int i=;i<=ca;++i)
if (cap[i].di<=dis[from[cap[i].loc]]&&unsafe[from[cap[i].loc]]==ti){
cap[i].di=;
unsafe[from[cap[i].loc]]=;
}
sort(cap+,cap++ca,cmp1);
while (cap[ca].di==&&ca>) ca--;
for (int i=head[];i;i=next[i])
if (unsafe[to[i]]==ti) list[++lis]=power[i];
sort(list+,list++lis,cmp3);
int l=,r=;
while (l<=ca&&r<=lis)
if (list[r]<=cap[l].di) l++,r++;
else break;
if (r>lis) return true;
else return false;
}
int main(){
num=;
scanf("%d",&n);
for (int u,v,i=;i<n;++i){
scanf("%d%d%lld",&u,&v,&w);
r+=w;
add(u,v,w);
}
scanf("%d",&m);
for (int i=;i<=m;++i)
scanf("%d",&em[i].loc);
fa[]=;
DFS();
dis[]=;
fa[]=;
memset(visit,,sizeof(visit));
for (int i=;i<=m;++i)
em[i].di=dis[em[i].loc];
sort(em+,em++m,cmp1);
pre();
l=;
ans=;
while (l<r){
ti=(l+r)>>;
if (work(ti)) ans=ti,r=ti;
else l=ti+;
}
if (l==r) if (work(l)) ans=l;
printf("%lld\n",ans);
return ;
}

神奇的代码

(代码写的巨烂无比qwq)

2012Noip提高组Day2 T3 疫情控制的更多相关文章

  1. [NOIP2012] day2 T3疫情控制

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

  2. 2012Noip提高组Day1 T3 开车旅行

    题目描述 小 A 和小 B 决定利用假期外出旅行,他们将想去的城市从 1 到 N 编号,且编号较小的 城市在编号较大的城市的西边,已知各个城市的海拔高度互不相同,记城市 i 的海拔高度为 Hi,城市 ...

  3. 一道搜索题【2013 noip提高组 DAY2 t3】华容道

    这篇不多说,具体的解释都在程序里 题目描述 [问题描述] 小 B 最近迷上了华容道,可是他总是要花很长的时间才能完成一次.于是,他想到用编程来完成华容道:给定一种局面, 华容道是否根本就无法完成,如果 ...

  4. 18/9/16牛客网提高组Day2

    牛客网提高组Day2 T1 方差 第一眼看就知道要打暴力啊,然而并没有想到去化简式子... 可能因为昨晚没睡好,今天上午困死 导致暴力打了一个半小时,还不对... #include <algor ...

  5. 【2012noip提高组】借教室

    在大学期间,经常需要租借教室.大到院系举办活动,小到学习小组自习讨论,都需要 向学校申请借教室.教室的大小功能不同,借教室人的身份不同,借教室的手续也不一样. 面对海量租借教室的信息,我们自然希望编程 ...

  6. 【未完成0.0】Noip2012提高组day2 解题报告

    第一次写一套题的解题报告,感觉会比较长.(更新中Loading....):) 题目: 第一题:同余方程 描述 求关于x的同余方程ax ≡ 1 (mod b)的最小正整数解. 格式 输入格式 输入只有一 ...

  7. NOIP2012 D2 T3 疫情控制 洛谷P1084

    题目链接:https://www.luogu.org/problemnew/show/P1084 算法:倍增,二分答案,贪心 + 瞎搞.. 背景:上学长的数论课啥也听不懂,于是前去提高组找安慰.不巧碰 ...

  8. 2013 Noip提高组 Day2

    3288积木大赛 正文 题目描述 春春幼儿园举办了一年一度的“积木大赛”.今年比赛的内容是搭建一座宽度为n的大厦,大厦可以看成由n块宽度为1的积木组成,第i块积木的最终高度需要是hi. 在搭建开始之前 ...

  9. 2012 Noip提高组 Day2

    1265. [NOIP2012] 同余方程 ★☆   输入文件:mod.in   输出文件:mod.out   简单对比时间限制:1 s   内存限制:128 MB [题目描述] 求关于 x 的同余方 ...

随机推荐

  1. 机器学习:K-Means聚类算法

    本文来自同步博客. 前面几篇文章介绍了回归或分类的几个算法,它们的共同点是训练数据包含了输出结果,要求算法能够通过训练数据掌握规律,用于预测新输入数据的输出值.因此,回归算法或分类算法被称之为监督学习 ...

  2. KafkaStream时间戳问题CreateTime = -1引起的程序中断

    Exception in thread "app-8835188a-e0a0-46da-ac2a-6820ec197628-StreamThread-1" org.apache.k ...

  3. Intellij IDEA 部署 项目在tomcat 原理

    https://www.zhihu.com/question/54757013 Intellij IDEA通过tomcat部署web项目的机制 IntelliJ IDEA通过Tomcat启动项目过程分 ...

  4. 使用html2canvas实现超出浏览器部分截图

    之前写过一篇关于 html2canvas如何在元素隐藏的情况下生成截图 的文章,后面发现还有个坑在等着我,就是如果合成图片太大,超出了浏览器的可视区域,那么超出部分是无法截图的.在网上找到了以下方法, ...

  5. larave框架的安装

    (1)中文官网:http://www.golaravel.com/ (2)composer下载与安装 1:composer网址:getcomposer.org 2:windows下载Composer- ...

  6. html块状元素、内联元素

    html块状元素.内联元素 原文在这 块级元素的分类 块级元素按照其应用于结构还是内容分为三种:结构化块状元素,终端块状元素,多目标块状元素. 一.结构化块状元素 这类元素用于构造文档的结构,一个好的 ...

  7. 传说中的纯CSS圆角代码

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xht ...

  8. C语言写的trim()函数

    C语言的标准库中缺少对字符串进行操作的trim()函数,使用起来有些不便,可以使用利用 strlen 和 isspace 函数以及指针来自己写一个. 1.strlen 函数 原型:extern int ...

  9. 15天玩转redis(mark,redis学习系列)

    转自:http://www.cnblogs.com/huangxincheng/p/4966258.html 双十一终于还是过去了,我负责的mongodb由于做了副本集,最终还是挺过去了,同事负责的r ...

  10. RunnableException与CheckedException

    Checked Exception 编译时异常 编译的时候检查你的代码可能在运行的时候抛出异常,这通常在编译的时候要去处理的. RunnableException 运行时异常,可以编译通过,但如果不处 ...