[树上倍增+二分答案][NOIP2012]运输计划
题目背景
公元 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]运输计划的更多相关文章
- [NOIP 2015]运输计划-[树上差分+二分答案]-解题报告
[NOIP 2015]运输计划 题面: A[NOIP2015 Day2]运输计划 时间限制 : 20000 MS 空间限制 : 262144 KB 问题描述 公元 2044 年,人类进入了宇宙纪元. ...
- NOIP2015 运输计划 (树上差分+二分答案)
---恢复内容开始--- 题目大意:给你一颗树,你可以把其中一条边的边权改成0,使给定的一些树链的权值和的最大值最小 把lenth定义为未修改边权时的答案 考虑二分答案,如果二分的答案成立,设修改成0 ...
- 洛谷P2680 运输计划(倍增LCA + 树上差分 + 二分答案)
[题目链接] [思路]: 根据题意可以明显看出,当所有任务都完成时的时间是最终的结果,也就是说本题要求,求出最小的最大值. 那这样的话就暗示了将答案二分,进行check. [check方法]: 如果说 ...
- 字符串(tjoi2016,heoi2016,bzoj4556)(sam(后缀自动机)+线段树合并+倍增+二分答案)
佳媛姐姐过生日的时候,她的小伙伴从某东上买了一个生日礼物.生日礼物放在一个神奇的箱子中.箱子外边写了 一个长为\(n\)的字符串\(s\),和\(m\)个问题.佳媛姐姐必须正确回答这\(m\)个问题, ...
- BZOJ 2783 树 - 树上倍增 + 二分
传送门 分析: 对每个点都进行一次二分:将该点作为链的底端,二分链顶端所在的深度,然后倍增找到此点,通过前缀和相减求出链的权值,并更新l,r. code #include<bits/stdc++ ...
- [NOIP2015] 提高组 洛谷P2680 运输计划
题目背景 公元 2044 年,人类进入了宇宙纪元. 题目描述 L 国有 n 个星球,还有 n-1 条双向航道,每条航道建立在两个星球之间,这 n-1 条航道连通了 L 国的所有星球. 小 P 掌管一家 ...
- [NOIP2015]运输计划 线段树or差分二分
目录 [NOIP2015]运输计划 链接 思路1 暴力数据结构 思路2 二分树上差分 总的 代码1 代码2 [NOIP2015]运输计划 链接 luogu 好久没写博客了,水一篇波. 思路1 暴力数据 ...
- 洛谷P1084 疫情控制 [noip2012] 贪心+树论+二分答案 (还有个小bugQAQ
正解:贪心+倍增+二分答案 解题报告: 正好想做noip的题目然后又想落实学长之前讲的题?于是就找上了这题 其实之前做过,70,然后实在细节太多太复杂就不了了之,现在再看一遍感觉又一脸懵了... 从标 ...
- BZOJ4326或洛谷2680 运输计划
BZOJ原题链接 洛谷原题链接 用\(LCA\)初始化出所有运输计划的原始时间,因为答案有单调性,所以二分答案,然后考虑检验答案. 很容易想到将所有超出当前二分的答案的运输计划所经过的路径标记,在这些 ...
随机推荐
- Python笔记:编码问题
1. python2的编码: python2中使用的是ASCII码,所以不支持中文,如果要在python2中写入中文编码,需要在文件头编写: #-*- encoding:utf-8 -*- 2. 不同 ...
- js基础面试篇
1,js中的new做了什么? function Person () { this.name = name; this.age = age; this.sex = sex this.sayName = ...
- 201772020113李清华《面向对象程序设计(java)》第十二周学习总结
1.实验目的与要求 (1) 掌握Java GUI中框架创建及属性设置中常用类的API: (2) 掌握Java GUI中2D图形绘制常用类的API: (3) 了解Java GUI中2D图形中字体与颜色的 ...
- 每日一练之贪心算法(P2587)
洛谷——P2587 [ZJOI2008]泡泡堂 两队人马进行比赛, 战斗力值各有差异, 如果一方获胜得两分,战平各得一分,失败不得分,求可取得的最佳战绩与最差战绩. 思路:1)最强的打得过最强的就直接 ...
- Docker 容器操作命令
容器是镜像的一个运行实例,镜像是静态的只读文件,而容器带有运行时需要的可写文件层.如果认为虚拟机是模拟运行的一整套操作系统(包括内核.应用运行态环境和其他系统环境)和跑在上面的应用,那么Docker容 ...
- 【STM32】临界区进入退出宏 OS_ENTER_CRITICAL() 和 OS_EXIT_CRITICAL()
宏函数展开为: #define OS_CRITICAL_METHOD 3 #if OS_CRITICAL_METHOD == 3 #define OS_ENTER_CRITICAL() {cpu_sr ...
- [原创] debian 9.3 搭建Jira+Confluence+Bitbucket项目管理工具(四) -- 安装crowd 3.1.2
[原创] debian 9.3 搭建Jira+Confluence+Bitbucket项目管理工具(四) -- 安装crowd 3.1.2 本来已经安装完毕, 并使用Jira集成的OAuth账户管理, ...
- 1.express中间件的简介
express中间件的意思 1, 中间件是一个模块.在js中,模块意味着函数,所以中间件是一个函数.那么这个函数长什么样子? 这还要从中间件的功能说起,它拦截http 服务器提供的请求和响应对象,执行 ...
- DOM节点遍历
"DOM2级遍历和范围"模块定义了两个用于辅助完成顺序遍历DOM结构的类型:NodeIterator 和 TreeWalker .这两个类型能够根据给定的节点对DOM结构进行深度优 ...
- spring 自定参数解析器(HandlerMethodArgumentResolver)
https://blog.csdn.net/u010187242/article/details/73647670