HDU 4123 Bob’s Race 树的直径 RMQ
Bob’s Race
Time Limit: 20 Sec
Memory Limit: 256 MB
题目连接
http://acm.hdu.edu.cn/showproblem.php?pid=4123
Description
Input
There are several test cases.
The first line of each test case contains two integers N and M. N is the number of houses, M is the number of queries.
The following N-1 lines, each contains three integers, x, y
and z, indicating that there is a road of length z connecting house x
and house y.
The following M lines are the queries. Each line contains an
integer Q, asking that at most how many people can take part in Bob’s
race according to the above mentioned rules and under the condition that
the“race difference”is no more than Q.
The input ends with N = 0 and M = 0.
(N<=50000 M<=500 1<=x,y<=N 0<=z<=5000 Q<=10000000)
Output
For each test case, you should output the answer in a line for each query.
Sample Input
1 2 3
2 3 4
4 5 3
3 4 2
1
2
3
4
5
0 0
Sample Output
1
3
3
3
5
HINT
题意
一个城镇有N个住户,N-1条路连接两个住户,保证N个住户联通,M次询问,给定N条边的信息,包括连
接的住户序号以及路的长度。然后是M次询问,每次询问Q,要求找到最长的连续序号,使得Max(dis[i]) - Min(dis[i]) ≤
Q(l≤i≤r),输出最大的r-l+1。dis[i]为从第i个住户出发,不重复走过路能移动的最远距离。
题解:
dis[i]一定是点到直径的某个点的距离,所以我们两次dfs求出直径,然后两次dfs求出距离就好了
至于第二问,对于每个询问,我们可以O(N)扫一遍就好了
代码
#include<iostream>
#include<stdio.h>
#include<cstring>
#include<vector>
using namespace std; vector<pair<int,int> > Q[];
int d[];
int n,m;
int left1,l_num;
int Right,r_num;
int dpMax[][], dpMin[][];
void dfs1(int x,int pre,int len,int type)
{
if(type == && l_num < len)
{
l_num = len;
left1 = x;
}
if(type == && r_num < len)
{
r_num = len;
Right = x;
}
for(int i=;i<Q[x].size();i++)
{
pair<int,int> K = Q[x][i];
if(K.first == pre)continue;
dfs1(K.first,x,len + K.second,type);
}
}
void dfs2(int x,int pre,int len)
{
d[x]=max(d[x],len);
for(int i=;i<Q[x].size();i++)
{
pair<int,int> K = Q[x][i];
if(K.first == pre)continue;
dfs2(K.first,x,len + K.second);
}
}
void rmq_init() {
for (int i = ; i <= n; i++)
dpMax[i][] = dpMin[i][] = d[i]; for (int k = ; (<<k) <= n; k++) {
for (int i = ; i + (<<k) - <= n; i++) {
dpMax[i][k] = max(dpMax[i][k-], dpMax[i+(<<(k-))][k-]);
dpMin[i][k] = min(dpMin[i][k-], dpMin[i+(<<(k-))][k-]);
}
}
} int rmq_query(int l, int r) {
int k = ;
while ((<<(k+)) <= r - l + ) k++;
return max(dpMax[l][k], dpMax[r-(<<k)+][k]) - min(dpMin[l][k], dpMin[r-(<<k)+][k]);
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
if(n==&&m==)break;
memset(d,,sizeof(d));
memset(dpMax,,sizeof(dpMax));
memset(dpMin,,sizeof(dpMin));
for(int i=;i<=n;i++)
Q[i].clear();
for(int i=;i<n;i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
Q[x].push_back(make_pair(y,z));
Q[y].push_back(make_pair(x,z));
}
left1 = l_num = Right = r_num = ; dfs1(,-,,);
dfs1(left1,-,,);
dfs2(left1,-,);
dfs2(Right,-,);
rmq_init();
while (m--) {
int ans = , mv = ;
int QQ;
scanf("%d", &QQ);
for (int i = ; i <= n; i++) {
while (mv <= i && rmq_query(mv , i) > QQ) mv++;
ans = max(ans, i - mv + );
}
printf("%d\n", ans);
} }
}
HDU 4123 Bob’s Race 树的直径 RMQ的更多相关文章
- hdu 4123 Bob’s Race 树的直径+rmq+尺取
Bob’s Race Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Probl ...
- HDU 4123 Bob’s Race 树的直径+单调队列
题意: 给定n个点的带边权树Q个询问. 以下n-1行给出树 以下Q行每行一个数字表示询问. 首先求出dp[N] :dp[i]表示i点距离树上最远点的距离 询问u, 表示求出 dp 数组中最长的连续序列 ...
- HDU 4123 Bob’s Race 树的直径+ST表
Bob’s Race Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=41 ...
- HDU 4123 Bob's Race:树的直径 + 单调队列 + st表
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4123 题意: 给你一棵树,n个节点,每条边有长度. 然后有m个询问,每个询问给定一个q值. 设dis[ ...
- HDU 4123 Bob’s Race 树形dp+单调队列
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4123 Time Limit: 5000/2000 MS (Java/Others) Memory L ...
- hdu 4123 Bob’s Race (dfs树上最远距离+RMQ)
C - Bob’s Race Time Limit:2000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Subm ...
- HDU 4123 Bob’s Race(树形DP,rmq)
Bob’s Race Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- HDU 4123 Bob’s Race(RMQ)
题意是说给出一棵树,N(10^5)个顶点,以及每条边的权值,现在需要选择连续的K个点(顶点编号连续),可以被选出来的条件是: 若d[i]代表顶点i到树上其他点的距离的最大值,使得区间[a, b]的d值 ...
- hdu 4607 Park Visit 求树的直径
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4607 题目大意:给你n个点,n-1条边,将图连成一棵生成树,问你从任意点为起点,走k(k<=n) ...
随机推荐
- Mac终端编译运行C++
1.在编辑器中写好C++代码 2.打开终端打开文件对应的地址 3.用g++命令来编译.cpp文件 4.用./文件名来运行 观察文件的目录可发现 g++ 源文件名 编译源文件,产生a.out ./文件名 ...
- 【JSP】JSP向MySQL写入|读出中文数据——乱码问题
注意第14行
- Oracle 跟踪事件 set event
一.Oracle跟踪文件 Oracle跟踪文件分为三种类型,一种是后台报警日志文件,记录数据库在启动.关闭和运行期间后台进程的活动情况,如表空间创建.回滚段创建.某些alter命令.日志切换.错误消息 ...
- Super关键字
一.super关键字
- NumberSeekBar 可任意拖动和自动
package com.example.numberseekbar; import android.content.Context; import android.content.res.Resour ...
- 如何清除win7开机密码
一.电脑已经登录到系统,但是忘记了密1对于这种情况是最简单的,其实只需要将密码取消就可以了右键单击桌面上我的电脑,选择管理即可进入计算机管理界面2依次展开系统工具--本地用户和组--用户,在右侧选择要 ...
- delphi ole word
源代码如下: //Word打印(声明部分) wDoc,wApp:Variant; function PrnWordBegin(tempDoc,docName:String):boolean; func ...
- jenkins 命令行 CLI jenkins-cli.jar
部署好jenkins后,一般都是通过jenkins提供的web界面来操作jenkins. 而有些场景则需要通过命令来操作jenkins,例如通过脚本操作jenkins. 在jenkins提供的web界 ...
- JDBC获取表的主键
JDBC获取表的主键 案例,创建订单,并根据订单号向订单明细表插入数据 sql语句: 创建两表 create table orders( id number(4) primary key, cus ...
- Dubbo服务重载方法在JDK1.8上调用出错的问题(待解决)
据说是javassist版本太低不支持JDK1.8,但是测试升级了还是调用出错.预留,待解决.