题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4123

题意:

  给你一棵树,n个节点,每条边有长度。

  然后有m个询问,每个询问给定一个q值。

  设dis[i]为:从节点i出发,不重复经过节点,所能够走的最远距离。

  每次询问问你:区间[l,r]最长能有多长,同时保证 max{dis[i]} - min{dis[i]} <= q (i∈[l,r])

题解:

  首先有一个结论:

    从树上的任意一个节点出发,尽可能往远走,最终一定会到达树的直径的两个端点之一。

  所以先两遍dfs1,找出直径的两个端点。

  然后分别从两个端点dfs2,求出所有节点的dis[i]。

  因为节点必须选编号连续的一段区间,所以可以用到单调队列。

  枚举每个节点i加入队首。

  然后对于每个i,不断地丢掉队尾pos++,直到当前的区间[pos,i]符合条件。

  那么每次都需要判断是否有 max{dis[i]} - min{dis[i]} <= q (i∈[pos,i])

  这就要用到st表了,然后O(1)判断就好。

AC Code:

 #include <iostream>
#include <stdio.h>
#include <string.h>
#include <vector>
#define MAX_N 50005
#define MAX_K 20 using namespace std; struct Edge
{
int dest;
int len;
Edge(int _dest,int _len)
{
dest=_dest;
len=_len;
}
Edge(){}
}; int n,m;
int maxd;
int st,ed;
int dis[MAX_N];
int lg[MAX_N];
int maxt[MAX_N][MAX_K];
int mint[MAX_N][MAX_K];
vector<Edge> edge[MAX_N]; void read()
{
for(int i=;i<=n;i++) edge[i].clear();
int x,y,z;
for(int i=;i<n;i++)
{
cin>>x>>y>>z;
edge[x].push_back(Edge(y,z));
edge[y].push_back(Edge(x,z));
}
} void dfs1(int now,int p,int d,int &v)
{
if(d>maxd)
{
maxd=d;
v=now;
}
for(int i=;i<edge[now].size();i++)
{
Edge temp=edge[now][i];
if(temp.dest!=p) dfs1(temp.dest,now,d+temp.len,v);
}
} void dfs2(int now,int p,int d)
{
dis[now]=max(dis[now],d);
for(int i=;i<edge[now].size();i++)
{
Edge temp=edge[now][i];
if(temp.dest!=p) dfs2(temp.dest,now,d+temp.len);
}
} void init_st()
{
lg[]=-;
for(int i=;i<=n;i++)
{
lg[i]=lg[i>>]+;
maxt[i][]=mint[i][]=dis[i];
}
for(int k=;(<<k)<=n;k++)
{
for(int i=;i+(<<k)-<=n;i++)
{
maxt[i][k]=max(maxt[i][k-],maxt[i+(<<(k-))][k-]);
mint[i][k]=min(mint[i][k-],mint[i+(<<(k-))][k-]);
}
}
} int query_max(int l,int r)
{
int k=lg[r-l+];
return max(maxt[l][k],maxt[r-(<<k)+][k]);
} int query_min(int l,int r)
{
int k=lg[r-l+];
return min(mint[l][k],mint[r-(<<k)+][k]);
} void work()
{
maxd=-;
dfs1(,-,,st);
maxd=-;
dfs1(st,-,,ed);
memset(dis,-,sizeof(dis));
dfs2(st,-,);
dfs2(ed,-,);
init_st();
while(m--)
{
int q;
cin>>q;
int ans=;
int pos=;
for(int i=;i<=n;i++)
{
while(query_max(pos,i)-query_min(pos,i)>q) pos++;
ans=max(ans,i-pos+);
}
cout<<ans<<endl;
}
} int main()
{
while(cin>>n>>m)
{
if(n== && m==) break;
read();
work();
}
}

HDU 4123 Bob's Race:树的直径 + 单调队列 + st表的更多相关文章

  1. HDU 4123 Bob’s Race 树的直径+单调队列

    题意: 给定n个点的带边权树Q个询问. 以下n-1行给出树 以下Q行每行一个数字表示询问. 首先求出dp[N] :dp[i]表示i点距离树上最远点的距离 询问u, 表示求出 dp 数组中最长的连续序列 ...

  2. 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 ...

  3. hdu 4123 Bob’s Race 树的直径+rmq+尺取

    Bob’s Race Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Probl ...

  4. POJ 3162 Walking Race(树的直径+单调队列)

    题目大意:对一棵树,求出从每个结点出发能到走的最长距离(每个结点最多只能经过一次),将这些距离按排成一个数组得到dis[1],dis[2],dis[3]……dis[n] ,在数列的dis中求一个最长的 ...

  5. 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 ...

  6. HDU 4123 Bob’s Race 树形dp+单调队列

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4123 Time Limit: 5000/2000 MS (Java/Others) Memory L ...

  7. hdu 4123 Bob’s Race (dfs树上最远距离+RMQ)

    C - Bob’s Race Time Limit:2000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Subm ...

  8. HDU 4123(树的直径+单调队列)

    Bob’s Race Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  9. 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 ...

随机推荐

  1. iOS UIView添加阴影

    _bottomView.layer.masksToBounds = NO; _bottomView.backgroundColor = [UIColor whiteColor]; _bottomVie ...

  2. Apache配置压缩优化时报错——undefined symbol: inflateEnd

    Apache配置压缩优化时报错——undefined symbol: inflateEnd 环境:CentOS 6.4 软件版本:httpd-2.4.6 apr-1.4.8 apr-util-1.5. ...

  3. 【整理】Android中EditText中的InputType类型含义与如何定义( 转 )

    转自:[整理]Android中EditText中的InputType类型含义与如何定义 用到的时候查到了这篇文章觉得很不错,就在此记录下. [背景] 经过一些Android中EditText方面的折腾 ...

  4. [原]Nginx+Lua服务端合并静态文件

    http://homeway.me 0x01.About 源代码已经上传到github:https://github.com/grasses/nginx-lua-static-merger nginx ...

  5. Nginx (简体中文)

    博文地址:https://wiki.archlinux.org/index.php/Nginx_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)#.E5.AE.89.E8. ...

  6. TP框架---thinkphp中ajax分页

    //点击类别后要显示的内容 public function pagechuli3()//这个方法的功能是根据ajax传过来的值查询数据,再将查询出来的数据返回到ajax,返回的默认是JSON类型. { ...

  7. Generally a good method to avoid this is to randomly shuffle the data prior to each epoch of training.

    http://ufldl.stanford.edu/tutorial/supervised/OptimizationStochasticGradientDescent/

  8. 【python】-- 模块、os、sys、time/datetime、random、logging、re

    模块 模块,用一堆代码实现了某个功能的代码集合. 类似于函数式编程和面向过程编程,函数式编程则完成一个功能,其他代码用来调用即可,提供了代码的重用性和代码间的耦合.而对于一个复杂的功能来,可能需要多个 ...

  9. linux c编程:Posix消息队列

    Posix消息队列可以认为是一个消息链表. 有足够写权限的线程可以往队列中放置消息, 有足够读权限的线程可以从队列中取走消息 在某个进程往一个队列写入消息前, 并不需要另外某个进程在该队列上等待消息的 ...

  10. Symfony 没有找到数据库驱动An exception occured in driver: could not find driver

    如果一直报这个错误, 第一,你本地没有相关的数据库驱动(mysql:-->pdo_myql,postgresql-->pdo_pgsql等); 需要执行 php -m|grep -i pd ...