HDU 4123 Bob’s Race 树形dp+单调队列
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=4123
Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
#### 问题描述
> Bob wants to hold a race to encourage people to do sports. He has got trouble in choosing the route. There are N houses and N - 1 roads in his village. Each road connects two houses, and all houses are connected together. To make the race more interesting, he requires that every participant must start from a different house and run AS FAR AS POSSIBLE without passing a road more than once. The distance difference between the one who runs the longest distance and the one who runs the shortest distance is called “race difference” by Bob. Bob does not want the “race difference”to be more than Q. The houses are numbered from 1 to N. Bob wants that the No. of all starting house must be consecutive. He is now asking you for help. He wants to know the maximum number of starting houses he can choose, by other words, the maximum number of people who can take part in his race.
#### 输入
> 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 For each test case, you should output the answer in a line for each query.
####样例输入
> 5 5
> 1 2 3
> 2 3 4
> 4 5 3
> 3 4 2
> 1
> 2
> 3
> 4
> 5
> 0 0
样例输出
1
3
3
3
5
题意
给你一颗树,如果设置的起点包含点v,那么从那里出发的选手就会跑到离它最远的顶点上。现在每个查询给你一个q,让你选最多的起点,同时保证所有选手中跑的最大距离和最小距离要小于等于q。
题解
先用树形dp处理直径的方式处理出每个点能跑的最远距离。然后就是一个裸的单调队列的问题了。(单调队列是可以维护区间最值的),当然,你用rmq或线段树维护也是可以的。
代码
#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<stack>
#include<ctime>
#include<vector>
#include<cstdio>
#include<string>
#include<bitset>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<functional>
using namespace std;
#define X first
#define Y second
#define mkp make_pair
#define lson (o<<1)
#define rson ((o<<1)|1)
#define mid (l+(r-l)/2)
#define sz() size()
#define pb(v) push_back(v)
#define all(o) (o).begin(),(o).end()
#define clr(a,v) memset(a,v,sizeof(a))
#define bug(a) cout<<#a<<" = "<<a<<endl
#define rep(i,a,b) for(int i=a;i<(b);i++)
#define scf scanf
#define prf printf
typedef long long LL;
typedef vector<int> VI;
typedef pair<int,int> PII;
typedef vector<pair<int,int> > VPII;
const int INF=0x3f3f3f3f;
const LL INFL=0x3f3f3f3f3f3f3f3fLL;
const double eps=1e-8;
const double PI = acos(-1.0);
//start----------------------------------------------------------------------
const int maxn=50505;
int dp[maxn][2],id[maxn];
int arr[maxn];
int n,m;
VPII G[maxn];
///单调队列,用优先队列的t了,手写了一个O(n)的。
struct Queue{
int lis[maxn],f,r;
int clk[maxn];
void init(){ f=1,r=0; }
bool empty(){ return f>r; }
void pop_front(){ f++; }
void pop_back(){ r--; }
void push(int v,int t){
lis[++r]=v;
clk[r]=t;
}
int front(int istim){
if(empty()) return -1;
if(istim) return clk[f];
return lis[f];
}
int rear(int istim){
if(istim) return clk[r];
return lis[r];
}
}q1,q2;
///树形dp求每个点的最远顶点距离
void dfs(int u,int fa){
id[u]=-1;
dp[u][0]=dp[u][1]=0;
rep(i,0,G[u].sz()){
int v=G[u][i].X,w=G[u][i].Y;
if(v==fa) continue;
dfs(v,u);
///更新最大值
if(dp[u][0]<dp[v][0]+w){
dp[u][1]=dp[u][0];
///更新次大
dp[u][0]=dp[v][0]+w;
id[u]=v;
}else if(dp[u][1]<dp[v][0]+w){
///更新次大
dp[u][1]=dp[v][0]+w;
}
}
}
///用父亲下来的最远距离更新最值
void dfs2(int u,int fa,int ma){
dp[u][0]=max(dp[u][0],ma);
rep(i,0,G[u].sz()){
int v=G[u][i].X,w=G[u][i].Y;
if(v==fa) continue;
if(id[u]==v){
dfs2(v,u,max(dp[u][1],ma)+w);
}else{
dfs2(v,u,max(dp[u][0],ma)+w);
}
}
}
void init(){
for(int i=1;i<=n;i++) G[i].clear();
}
int main() {
while(scf("%d%d",&n,&m)==2&&n){
init();
rep(i,0,n-1){
int u,v,w;
scf("%d%d%d",&u,&v,&w);
G[u].pb(mkp(v,w));
G[v].pb(mkp(u,w));
}
dfs(1,-1);
dfs2(1,-1,0);
for(int i=1;i<=n;i++) arr[i]=dp[i][0];
while(m--){
int q; scf("%d",&q);
///q1小,q2大,单调队列
q1.init(),q2.init();
int l=1,Ma=1;
for(int i=1;i<=n;i++){
while(!q1.empty()&&q1.rear(0)>=arr[i]) q1.pop_back();
while(!q2.empty()&&q2.rear(0)<=arr[i]) q2.pop_back();
q1.push(arr[i],i);
q2.push(arr[i],i);
while(q2.front(0)-q1.front(0)>q){
l++;
while(q1.front(1)<l) q1.pop_front();
while(q2.front(1)<l) q2.pop_front();
}
Ma=max(Ma,i-l+1);
}
prf("%d\n",Ma);
}
}
return 0;
}
/*
5 3
1 2 9
3 4 5
3 5 3
*/
HDU 4123 Bob’s Race 树形dp+单调队列的更多相关文章
- POJ - 3162 Walking Race 树形dp 单调队列
POJ - 3162Walking Race 题目大意:有n个训练点,第i天就选择第i个训练点为起点跑到最远距离的点,然后连续的几天里如果最远距离的最大值和最小值的差距不超过m就可以作为观测区间,问这 ...
- 【POJ3162】Walking Race 树形dp+单调队列+双指针
题目大意:给定一棵 N 个节点的无根树,边有边权,现生成一个序列 d,d[i] 表示 i 号节点到树上其他节点距离的最大值.给定一个 m,求 d 序列中最大值和最小值之差不超过 m 的最长连续段的长度 ...
- (noip模拟二十一)【BZOJ2500】幸福的道路-树形DP+单调队列
Description 小T与小L终于决定走在一起,他们不想浪费在一起的每一分每一秒,所以他们决定每天早上一同晨练来享受在一起的时光. 他们画出了晨练路线的草图,眼尖的小T发现可以用树来描绘这个草图. ...
- 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:树的直径 + 单调队列 + st表
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4123 题意: 给你一棵树,n个节点,每条边有长度. 然后有m个询问,每个询问给定一个q值. 设dis[ ...
- HDU 4123 Bob’s Race 树的直径+单调队列
题意: 给定n个点的带边权树Q个询问. 以下n-1行给出树 以下Q行每行一个数字表示询问. 首先求出dp[N] :dp[i]表示i点距离树上最远点的距离 询问u, 表示求出 dp 数组中最长的连续序列 ...
- 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 树的直径+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 树的直径 RMQ
Bob’s Race Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=41 ...
随机推荐
- MongoDB登录验证及用户管理
一.超级管理员创建及开启登录验证 如果MongoDB要开启登录验证,必须在开启登录验证之前先创建好超级管理员,否则无法登录数据库! 例如,创建一个超级管理员admin,关联给admin数据库,角色设置 ...
- Bluebox Security最新提报Android漏洞的初步探讨(转)
Bluebox Security在7月3号的时候,在官网上发布了一个据称99% Android机器都有的一个漏洞.国内最早在4号开始有媒体报道,并持续升温.该漏洞可使攻击者在不更改Android应用 ...
- mfc 类成员函数
知识点 类成员变量初值 类的构造函数 类成员函数 类成员函数的位置 一.类成员变量初值 二.类的构造函数 构造函数 是一种特殊的方法,主要用来在创建对象时初始化对象,即为对象成员变量赋初始值. 构造函 ...
- 05- views视图层
1.配置index 主url from django.contrib import admin from django.urls import path, re_path, include urlpa ...
- 7 stark组件介绍、配置、2层url
1.django的admin配置 model.py from django.db import models # Create your models here. class UserInfo(mod ...
- [ONTAK2010]Peaks kruskal重构树,主席树
[ONTAK2010]Peaks kruskal重构树练手题. LG传送门竟然不强制在线?看到离线水过很不爽:B站强制在线版传送门 看到"询问从点\(v\)开始只经过困难值小于等于\(x\) ...
- matlab GUI工作原理
例如,用GUIDE创建名为ceshi的GUI程序,其m文件的主函数有如下形式.那么,打开该GUI时,它到底是怎么运行的呢?以下略作小结,欢迎大家补充 function varargout = cesh ...
- JDBC连接数据库及其执行操作
作者:Alvin 功能:数据库连接与实现增删改查 时间:2019年3月4日08点33分 参考文章:https://www.2cto.com/database/201805/743741.html 一. ...
- 为什么Python类成员的调用和声明必须有"this"?
Python的这种设计是作者从Modula-3中借鉴来的,在后面使用的情况看来,这个设计也是比较成功的.我们对比Python和C++讨论一下这个问题: Modula-3是上世纪80年代末数字设备公司( ...
- Cisco Packet Tracer中通过集线器组网
Cisco Packet Tracer中可以通过集线器将多台电脑完成通信. Cisco Packet Tracer 6.2.0 一.添加三台电脑设备 1.按照下图1.2步骤操作,2步骤执行三次,拖拽P ...