首页 技术 正文
技术 2022年11月15日
0 收藏 970 点赞 4,266 浏览 3186 个字
时间限制 : 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 ;
}
相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,028
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,518
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,365
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,146
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,780
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,857