时间限制 : 20000 MS   空间限制 : 128000 KB
评测说明 : 2s,128m
问题描述

H 国有 n 个城市,这 n 个城市用 n-1 条双向道路相互连通构成一棵树,1 号城市是首都,也是树中的根节点。
H 国的首都爆发了一种危害性极高的传染病。当局为了控制疫情,不让疫情扩散到边境城市(叶子节点所表示的城市),决定动用军队在一些城市建立检查点,使得从首都到边境城市的每一条路径上都至少有一个检查点,边境城市也可以建立检查点。但特别要注意的是,首都是不能建立检查点的。现在,在 H国的一些城市中已经驻扎有军队,且一个城市可以驻扎多个军队。

一支军队可以在有道路连接的城市间移动,并在除首都以外的任意一个城市建立检查点,且只能在一个城市建立检查点。一支军队经过一条道路从一个城市移动到另一个城市所需要的时间等于道路的长度(单位:小时)。请问最少需要多少个小时才能控制疫情。注意:不同的军队可以同时移动。

输入格式

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

输出格式

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

样例输入 1


1 2 1 
1 3 2 
3 4 3 

2 2

样例输出 1

3

样例输入 2

10
2 1 3
2 3 4
1 4 7
5 1 9
6 1 2
4 7 9
7 8 8
9 8 8
1 10 2
5
2 8 5 4 2

样例输出 2

9

样例输入 3

10
1 2 15606
3 1 2777
4 3 2008
1 5 29898
1 6 31457
7 5 4630
6 8 32496
3 9 27660
10 9 29090
4
9 5 10 3

样例输出 3

56750

提示

【输入输出样例说明】
第一支军队在 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

【分析】
  首先这道题
【标程】
 #include<cstdio>
#include<algorithm>
#include<cctype>
#define ll long long
#define R register int
#define For(i, s, n) for (R i = s; i <= n; ++ i)
#define Getch() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1 ++)
#define maxn 50003
#define Log 17
using namespace std;
int n, u, v, w, m, tot, na, nb;
int End[maxn << ], Len[maxn << ], Next[maxn << ], Last[maxn], Army[maxn], F[maxn][Log + ], vis[maxn], used[maxn], restbj[maxn];
ll ans, l, r, Mid, Dis[maxn][Log + ], restmin[maxn];
char buf[ << ], *p1 = buf, *p2 = buf, obuf[ << ], *O = obuf;
struct node{
int id;
ll rest;
}a[maxn], b[maxn];
inline int read() {
int x = , f = ;
char ch = Getch();
while(!isdigit(ch)){if (ch == '-')f = -; ch = Getch();}
while(isdigit(ch))x = x * + (ch ^ ), ch = Getch();
return x * f;
}
void write(long long x) {
if (x > ) write(x / );
*O ++ = x % + '';
}
void Add(int x, int y, int z) {
End[++ tot] = y;
Len[tot] = z;
Next[tot] = Last[x];
Last[x] = tot;
}
void DFS(int x, int Las_, ll Gone) {
F[x][] = Las_;
Dis[x][] = Gone;
For (i, , Log) {
F[x][i] = F[F[x][i - ]][i - ];
Dis[x][i] = Dis[x][i - ] + Dis[F[x][i - ]][i - ];
}
for (R i = Last[x]; i != ; i = Next[i])
if (End[i] != Las_)DFS(End[i], x, Len[i]);
}
void ini() {
n = read();
scanf("%d", &n);
For (i, , n - ) {
u = read();
v = read();
w = read();
Add(u, v, w);
Add(v, u, w);
r += w;
}
DFS(, , );
m = read();
scanf("%d", &m);
For (i, , m)Army[i] = read();
}
bool cmp(node x,node y) {
return x.rest > y.rest;
}
int checkok(int x, int las){ //dfs找未被“封死”的子树
R bj = , i, bbj = ;
if (vis[x])return ;
for (i = Last[x]; i != ; i = Next[i]) {
if (End[i] == las)continue;
bbj = ;
if (!checkok(End[i], x)) {
bj = ;
if (x == )b[++ nb].id = End[i], b[nb].rest = Len[i];
else return ;
}
}
if(!bbj)return ;
return bj;
}
bool Check(ll Lim) {
R i, j, x, now;
ll num;
na = nb = ;
For (i, , n)vis[i] = restbj[i] = ;
For (i, , m)used[i] = ;
For (i, , m) {
x = Army[i], num = ;
for (j = ; j >= ; -- j) //上提军队
if (F[x][j] > && num + Dis[x][j] <= Lim)
num += Dis[x][j], x = F[x][j];
if (F[x][] == && num + Dis[x][] <= Lim){ //处理剩余路程
a[++ na].rest = Lim - num - Dis[x][], a[na].id = i;
if (!restbj[x] || a[na].rest < restmin[x])
restmin[x] = a[na].rest, restbj[x] = i;
} else vis[x] = ;
}
if (checkok(, ))return ;
sort(a + , a + + na, cmp), sort(b + , b + + nb, cmp); //军队在子树间转移
now = ;
used[] = ;
For (i, , nb) {
if (!used[restbj[b[i].id]]) {
used[restbj[b[i].id]] = ;
continue;
}
while (now <= na && (used[a[now].id] || a[now].rest < b[i].rest))++ now;
if (now > na)return ;
used[a[now].id] = ;
}
return ;
}
void solve() {
while (l <= r) {
Mid = (l + r) >> ;
if (Check(Mid)) {
ans = Mid;
r = Mid - ;
} else l = Mid + ;
}
write(ans);
}
int main() {
ini();
solve();
fwrite(obuf, O - obuf, , stdout);
return ;
}

A 【NOIP2012 day2】疫情控制的更多相关文章

  1. 【NOIP2012】 疫情控制

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

  2. [LOJ2607]【NOIP2012】疫情控制

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

  3. 【noip2012】疫情控制

    题意: 给出一颗n个节点有边权的树 和m个军队所在的位置 军队从某节点移动到相邻节点要花费边长度的时间 求最少要多少时间使得根节点(编号为1)到每个叶子的路径上最少有一支军队(根节点不能有军队) 题解 ...

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

    洛谷上的题目链接,题目不在赘述 题解 既然要时间最短,首先考虑二分. 因此,考虑二分时间,问题转换为如何检查能否到达. 如果一支军队一直向上走,能够到达根节点,那么他可以通过根节点到达其他的节点,因此 ...

  5. NOIP2012 D2T3 疫情控制 题解

    题面 这道题由于问最大值最小,所以很容易想到二分,但怎么验证并且如何实现是这道题的难点: 首先我们考虑,对于一个军队,尽可能的往根节点走(但一定不到)是最优的: 判断一个军队最远走到哪可以树上倍增来实 ...

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

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

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

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

  8. NOIP2012 疫情控制 题解(LuoguP1084)

    NOIP2012 疫情控制 题解(LuoguP1084) 不难发现,如果一个点向上移动一定能控制更多的点,所以可以二分时间,判断是否可行. 但根节点不能不能控制,存在以当前时间可以走到根节点的点,可使 ...

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

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

  10. 疫情控制 blockade

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

随机推荐

  1. 《一步步成为 Hacker_Day 01》

    环境搭建 传统运行模式 - 一台机器同时只能运行一个操作系统 |:----------|----------:| | 应用程序 | 应用程序 | |:----------|----------:| | ...

  2. JetBrains全系列产品2019.3.2注解教程

    1.JetBrains官方网站 https://www.jetbrains.com/ JetBrains是一家捷克的软件开发公司 IDE工具: * IntelliJ IDEA    一套智慧型的Jav ...

  3. 如何使用Kibana

    目录 前言 一.安装 二.加载自定义索引 三.如何搜索数据 四.如何切换中文 五.如何使用控制台 六.可视化图表 七.使用仪表盘 前言 Kibana 是为 Elasticsearch设计的开源分析和可 ...

  4. PDA程序开发的运行配置

    前言:因为这个项目是公司一直在做的项目,所以只是简单说一下我从下载项目到成功运行的配置 开发工具:APICloud.雷神模拟器.Visusl studio vs配置: 1.svn下载后台代码后,修改w ...

  5. jQuery实现颜色打字机

    效果:每个字逐个显示出来,并且每个字都有随机颜色 $(function(){ var str="早起的鸟儿有虫吃,早起的虫儿被鸟吃!由此天赋+勤奋=成功;先天不足+同等勤奋=还是失败!天赋的 ...

  6. 建议20:建议通过Function扩展类型

    JavaScript允许为语言的基本数据类型定义方法.通过Object.prototype添加原型方法,该方法可被所有的对象,.这样的方法对函数,数组,字符串,数字,正则表达式和布尔值都适用.例如,通 ...

  7. 对tf.nn.softmax的理解

    对tf.nn.softmax的理解 转载自律者自由 最后发布于2018-10-31 16:39:40 阅读数 25096  收藏 展开 Softmax的含义:Softmax简单的说就是把一个N*1的向 ...

  8. window 查看端口 杀端口

    最近写项目,总是出现端口被占用的问题,原来傻傻的把电脑重启一下,终于有一天受不了了,想要想办法解决.刚开始从网上找了好多教程,发现不行.开始自己尝试,终于,成功的将占用端口的进程杀掉.在此记录下过程( ...

  9. Journal of Proteome Research | Utilization of the Proteome Data Deposited in SRMAtlas for Validating the Existence of the Human Missing Proteins in GPM (解读人:梁嘉琪)

    文献名:Utilization of the Proteome Data Deposited in SRMAtlas for Validating the Existence of the Human ...

  10. 114 Flatten Binary Tree to Linked List [Python]

    114 Flatten Binary Tree to Linked List Given a binary tree, flatten it to a linked list in-place. 将二 ...