题目背景

公元 2044 年,人类进入了宇宙纪元。

题目描述

公元 2044 年,人类进入了宇宙纪元

L 国有 nn 个星球,还有 n-1n−1 条双向航道,每条航道建立在两个星球之间,这 n-1n−1 条航道连通了 LL 国的所有星球。

小 P 掌管一家物流公司, 该公司有很多个运输计划,每个运输计划形如:有一艘物流飞船需要从 u_iui​ 号星球沿最快的宇航路径飞行到 v_ivi​ 号星球去。显然,飞船驶过一条航道是需要时间的,对于航道 jj ,任意飞船驶过它所花费的时间为 t_jtj​ ,并且任意两艘飞船之间不会产生任何干扰。

为了鼓励科技创新, L 国国王同意小 P 的物流公司参与 L 国的航道建设,即允许小P 把某一条航道改造成虫洞,飞船驶过虫洞不消耗时间。

在虫洞的建设完成前小 P 的物流公司就预接了 mm 个运输计划。在虫洞建设完成后,这 mm 个运输计划会同时开始,所有飞船一起出发。当这 mm 个运输计划都完成时,小 P 的物流公司的阶段性工作就完成了。

如果小 P 可以自由选择将哪一条航道改造成虫洞, 试求出小 P 的物流公司完成阶段性工作所需要的最短时间是多少?

输入输出格式

输入格式:

第一行包括两个正整数 n, mn,m ,表示 L 国中星球的数量及小 P 公司预接的运输计划的数量,星球从 11 到 nn 编号。

接下来 n-1n−1 行描述航道的建设情况,其中第 ii 行包含三个整数 a_i, b_iai​,bi​ 和 t_iti​ ,表示第 ii 条双向航道修建在 a_iai​ 与 b_ibi​ 两个星球之间,任意飞船驶过它所花费的时间为 t_iti​ 。数据保证 1 \leq a_i,b_i \leq n1≤ai​,bi​≤n 且 0 \leq t_i \leq 10000≤ti​≤1000 。

接下来 mm 行描述运输计划的情况,其中第 jj 行包含两个正整数 u_juj​ 和 v_jvj​ ,表示第 jj 个运输计划是从 u_juj​ 号星球飞往 v_jvj​号星球。数据保证 1 \leq u_i,v_i \leq n1≤ui​,vi​≤n

输出格式:

输出文件只包含一个整数,表示小 P 的物流公司完成阶段性工作所需要的最短时间。

输入输出样例

输入样例:

6 3
1 2 3
1 6 4
3 1 7
4 3 6
3 5 5
3 6
2 5
4 5
输出样例:

11

二分移动所需的时间,在二分出的时间里用树上倍增检验能否实现
看了题解还是调到吐血,最后发现m放在n后面直接读入了..
代码:
 #include<algorithm>
#include<cstdio>
#include<cstring> const int Maxv = ;
int Book[Maxv], Head[Maxv], f[Maxv][], st[Maxv][], Top[Maxv], Tdis[Maxv], q[Maxv], rnum, tail, cnt, n, m;
bool lea[Maxv], vis[Maxv], fs; struct Node{
int u, v, w, next;
}e[Maxv << ]; struct Army{
int Rest, Top;
}army[Maxv]; int read(){
int x = , f = ;
char ch = getchar();
while (ch < '' || ch > '') {
if (ch == '-') {
f = -;
}
ch = getchar();
}
while (ch >= '' && ch <= '') {
x = x * + ch - '';
ch = getchar();
}
return x * f;
} void Add_Edge(int u, int v, int w){
cnt++;
e[cnt].v = v;
e[cnt].w = w;
e[cnt].next = Head[u];
Head[u] = cnt;
} void Add(int u, int v, int w){
Add_Edge(u, v, w);
Add_Edge(v, u, w);
} inline bool Cmp(int a, int b){
return a > b;
}
inline bool Cmpmin(Army a, Army b){
return a.Rest < b.Rest;
} inline bool Cmpmax(Army a, Army b){
return a.Rest > b.Rest;
} void dfs(int u, int father){
for (int i = Head[u]; i; i = e[i].next) {
int v = e[i].v;
if (v == father) {
continue;
}
f[v][] = u;
st[v][] = e[i].w;
dfs(v, u);
}
}//预处理倍增 void RMQ(){
for (int j = ; j <= ; j++) {
for (int i = ; i <= n; i++) {
f[i][j] = f[ f[i][j - ] ][j - ];
st[i][j] = st[i][j - ] + st[ f[i][j - ] ][j - ];
}
}
}//预处理倍增 void dfs1(int u, int father, int topf, int dist){
Top[u] = topf;
Tdis[u] = dist;
bool ft = false;
for (int i = Head[u]; i; i = e[i].next) {
int v = e[i].v;
if (v == father) {
continue;
}
ft = true;
dfs1(v, u, topf, dist);
}
if (!ft) {
lea[u] = true; //标记叶子节点
}
} void dfs2(int u, int father){
if (lea[u]) {
fs = true;
return;
}
for (int i = Head[u]; i; i = e[i].next) {
int v = e[i].v;
if (v == father) {
continue;
}
else if (vis[v]) {
continue;
}
dfs2(v, u);
if (fs) {
return;
}
}
} inline bool Look(int v){
fs = false;
dfs2(v, f[v][]);
return fs;
} inline bool judge(int mid){
memset(vis, false, sizeof(vis));
memset(q, , sizeof(q));
memset(army, , sizeof(army));
rnum = ;
tail = ;
for (int i = ; i <= m; i++) {
int tim = mid;
int now = Book[i];
bool syst = false;
while () {
for (int j = ; j >= ; j--) {
if (f[now][j] && st[now][j] <= tim) {
tim -= st[now][j];
now = f[now][j]; //向上跳
break;
}
if (j == || now == ) {
syst = true;
break; //停止条件
}
}
if (syst) {
break;
}
}
if (now == ) {
army[++rnum].Top = Top[ Book[i] ];
army[rnum].Rest = tim;
}
else {
vis[now] = true;
}
}
std::sort(army + , army + m + , Cmpmin);
for (int i = ; i <= m; i++) {
if (army[i].Rest < Tdis[ army[i].Top ]) {
if (!vis[ army[i].Top ] && Look(army[i].Top)) {
vis[ army[i].Top ] = true;
army[i].Rest = -;
}
}
}
std::sort(army + , army + m + , Cmpmax);
for (int i = Head[]; i; i = e[i].next) {
int v = e[i].v;
if (!vis[v] && Look(v)) {
q[++tail] = e[i].w;
}
}
std::sort(q + , q + tail + , Cmp);
for (int i = ; i <= tail; i++) {
if (army[i].Rest < q[i]) {
return false;
}
}
return true;
} int main(){
int u, v, w, R = , cnt1 = , Ans = ;
n = read(); for (int i = ; i < n; i++) {
u = read();
v = read();
w = read();
Add(u, v, w);
R += w;
}
dfs(, );
for (int i = Head[]; i; i = e[i].next) {
int v = e[i].v;
dfs1(v, , v, e[i].w);
}
RMQ();
m = read();
for (int i = ; i <= m; i++) {
Book[i] = read();
}
for (int i = Head[]; i; i = e[i].next) {
cnt1++;
}
if (cnt1 > m) {
printf("-1\n");
return ;
}
int L = ;
while (L <= R) {
int mid = (L + R) >> ;
if (judge(mid)) {
Ans = mid;
R = mid - ;
}
else {
L = mid + ;
}
}
printf("%d\n", Ans);
return ;
}
 

[树上倍增+二分答案][NOIP2012]运输计划的更多相关文章

  1. [NOIP 2015]运输计划-[树上差分+二分答案]-解题报告

    [NOIP 2015]运输计划 题面: A[NOIP2015 Day2]运输计划 时间限制 : 20000 MS 空间限制 : 262144 KB 问题描述 公元 2044 年,人类进入了宇宙纪元. ...

  2. NOIP2015 运输计划 (树上差分+二分答案)

    ---恢复内容开始--- 题目大意:给你一颗树,你可以把其中一条边的边权改成0,使给定的一些树链的权值和的最大值最小 把lenth定义为未修改边权时的答案 考虑二分答案,如果二分的答案成立,设修改成0 ...

  3. 洛谷P2680 运输计划(倍增LCA + 树上差分 + 二分答案)

    [题目链接] [思路]: 根据题意可以明显看出,当所有任务都完成时的时间是最终的结果,也就是说本题要求,求出最小的最大值. 那这样的话就暗示了将答案二分,进行check. [check方法]: 如果说 ...

  4. 字符串(tjoi2016,heoi2016,bzoj4556)(sam(后缀自动机)+线段树合并+倍增+二分答案)

    佳媛姐姐过生日的时候,她的小伙伴从某东上买了一个生日礼物.生日礼物放在一个神奇的箱子中.箱子外边写了 一个长为\(n\)的字符串\(s\),和\(m\)个问题.佳媛姐姐必须正确回答这\(m\)个问题, ...

  5. BZOJ 2783 树 - 树上倍增 + 二分

    传送门 分析: 对每个点都进行一次二分:将该点作为链的底端,二分链顶端所在的深度,然后倍增找到此点,通过前缀和相减求出链的权值,并更新l,r. code #include<bits/stdc++ ...

  6. [NOIP2015] 提高组 洛谷P2680 运输计划

    题目背景 公元 2044 年,人类进入了宇宙纪元. 题目描述 L 国有 n 个星球,还有 n-1 条双向航道,每条航道建立在两个星球之间,这 n-1 条航道连通了 L 国的所有星球. 小 P 掌管一家 ...

  7. [NOIP2015]运输计划 线段树or差分二分

    目录 [NOIP2015]运输计划 链接 思路1 暴力数据结构 思路2 二分树上差分 总的 代码1 代码2 [NOIP2015]运输计划 链接 luogu 好久没写博客了,水一篇波. 思路1 暴力数据 ...

  8. 洛谷P1084 疫情控制 [noip2012] 贪心+树论+二分答案 (还有个小bugQAQ

    正解:贪心+倍增+二分答案 解题报告: 正好想做noip的题目然后又想落实学长之前讲的题?于是就找上了这题 其实之前做过,70,然后实在细节太多太复杂就不了了之,现在再看一遍感觉又一脸懵了... 从标 ...

  9. BZOJ4326或洛谷2680 运输计划

    BZOJ原题链接 洛谷原题链接 用\(LCA\)初始化出所有运输计划的原始时间,因为答案有单调性,所以二分答案,然后考虑检验答案. 很容易想到将所有超出当前二分的答案的运输计划所经过的路径标记,在这些 ...

随机推荐

  1. python爬虫爬取京东、淘宝、苏宁上华为P20购买评论

    爬虫爬取京东.淘宝.苏宁上华为P20购买评论 1.使用软件 Anaconda3 2.代码截图 三个网站代码大同小异,因此只展示一个 3.结果(部分) 京东 淘宝 苏宁 4.分析 这三个网站上的评论数据 ...

  2. Android 开发 CoordinatorLayout 协调者布局 与 ConstraintLayout约束布局 两者的关系

    在摸索新技术是发现CoordinatorLayout 与 ConstraintLayout 会有冲突关系,所以就研究了一下他们之间的不兼容,被影响的方面.其实某种程度上来说是CoordinatorLa ...

  3. 四、Python-元组

    列表非常适合用于存储在程序运行期间可能变化的数据集.列表是可以修改的,这对处理网 站的用户列表或游戏中的角色列表至关重要. Python将不能修改的值称为不可变的,而不可变的列表被称为元组 一.元组( ...

  4. ORA-12560: TNS:protocol adapter error

    C:\Users\dong>sqlplus/nolog SQL*Plus: Release 11.2.0.1.0 Production on Mon Nov 19 14:12:51 2018 C ...

  5. go-001[常用命令]

    go env GOARCH="amd64"//这台机器的cpu 架构 GOBIN="/Applications/MAMP/htdocs/go/bin"  //工 ...

  6. cached_property的使用

    cached_property修饰过的函数,变成是对象的属性,该对象第一次引用该属性时,会调用函数,对象第二次引用该属性时就直接从词典中取了,这也说明引用属性是经过__getattritue__. c ...

  7. Linux 总线、设备、驱动模型 与 设备树

    1.总线.设备.驱动模型 本着高内聚.低耦合的原则,Linux 把设备驱动模型分为了总线.设备和驱动三个实体,这三个实体在内核里的职责分别如下: 设备和驱动向总线进行注册,总线负责把设备和对应的驱动绑 ...

  8. Python module ---- os

    os 模块Python标准库中的一个用于访问操作系统功能的模块,使用OS模块中提供的接口,可以实现跨平台访问.提供了一个统一的操作系统接口函数, 这些接口函数通常是平台指定的,os 模块能在不同操作系 ...

  9. 快速理解高性能HTTP服务端的负载均衡技术原理(转)

    1.前言 在一个典型的高并发.大用户量的Web互联网系统的架构设计中,对HTTP集群的负载均衡设计是作为高性能系统优化环节中必不可少的方案.HTTP负载均衡的本质上是将Web用户流量进行均衡减压,因此 ...

  10. cookie和session的区别及在Django中应用

    Django中Cookie和session应用 什么是cookie? cookie是客户端浏览器上的一个文件,以键值对进行保存,类似于字典的 {'key' : 'value'} ,与服务器端没有关系, ...