题目背景

公元 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. Ajax 请求请求 MVC WebAPI跨域问题;XMLHttpRequest cannot load

    问题:XMLHttpRequest cannot load http://192.168.1.4:9010//api/contacts. The 'Access-Control-Allow-Origi ...

  2. java.lang.IllegalArgumentException: Document base XXX does not exist or is not a readable directory解决方法

    一.配置Eclipse,部署项目 1.双击打开Tomcat设置页面 2.选择Modules模式 3.选择Add External Web Module.. (1)Document base:选择htd ...

  3. 69.纯 CSS 创作一个单元素抛盒子的 loader

    原文地址:https://segmentfault.com/a/1190000015470411#articleHeader0 HTML code: <div class="loade ...

  4. flink 学习

    一.运行 SockWordCount例子 1.到官网上下载 flink-1.6.2-bin-hadoop27-scala_2.11.tgz 然后加压出来 2.cd flink-1.6.2 3.打开fl ...

  5. 服务器上运行程序Out of memory 解决办法

    ****** 服务器上跑过程序经常能遇到out of memory 这个问题,下面是我经常在实验室碰到的解决方法. 1.使用命令nvidia-smi,看到GPU显存被占满: 2.尝试使用 ps aux ...

  6. JEECG 集成KiSSO单点登录实现统一身份认证

    JEECG 集成KiSSO单点登录实现统一身份认证 JEECG 如何为其他第三方系统实现统一身份认证服务,实现单点登录? 第三方系统如何对接呢? 今天为大家揭开这层面纱,让大家了解实质,使用它更快速的 ...

  7. SQL表变量和临时表

    一.表变量 表变量在SQL Server 2000中首次被引入.表变量的具体定义包括列定义,列名,数据类型和约束.而在表变量中可以使用的约束包括主键约束, 唯一约束,NULL约束和CHECK约束(外键 ...

  8. tabpanel如何隐藏页签表头以及基本用法总结

    tabpanel是extjs中一种比较常用的布局容器控件,也比较简单. ///1:相关的插件, var tabScrollerMenu = Ext.create("Ext.ux.TabScr ...

  9. keepliave

    keepalived的主要功能 1. healthcheck:           检查后端节点是否正常工作           如果发现后端节点异常,就将该异常节点从调度规则中删除:        ...

  10. Python txt文件读取写入字典的方法(json、eval)

    link:https://blog.csdn.net/li532331251/article/details/78203438 一.使用json转换方法 1.字典写入txt import json d ...