题意:Bob想要开一个运动会,有n个房子和n-1条路(一棵树),Bob希望每个人都从不同的房子开始跑,要求跑的尽可能远,而且每条路只能走最多一次。Bob希望所有人跑的距离的极差不大于q,如果起点的编号需要连续,那么最多多少个起点。

题解:首先求出每个点所能跑的最大距离(参考hdu2196),问题将转化成给n个数字,求差值不超过q的最大区间。m个询问,n个数,N<=50000 M<=500,所以对于每一次询问可以在O(n)的复杂度求解,st算法求区间最大最小值,尺取法求最大长度。

(去年做2196的时候做了两三天,这次一下就写出来了,而且没怎么调,1A,开心^_^

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long ll;
const int N = ;
const int INF = 0x5f5f5f5f;
struct Edge {
int to, cost, next;
} edge[N*];
int head[N];
int cnt_edge;
void add_edge(int u, int v, int c) {
edge[cnt_edge].to = v;
edge[cnt_edge].cost = c;
edge[cnt_edge].next = head[u];
head[u] = cnt_edge++;
} int d[N], mx[N], smx[N], mid[N], smid[N];
void dfs(int u, int fa) {
smx[u] = mx[u] = ;
mid[u] = smid[u] = ;
for (int i = head[u]; ~i; i = edge[i].next) {
int v = edge[i].to;
int c = edge[i].cost;
if (v == fa) continue;
dfs(v, u);
if (mx[v]+c > smx[u]) {
smx[u] = mx[v]+c;
smid[u] = v;
}
if (smx[u] > mx[u]) {
swap(smx[u], mx[u]);
swap(smid[u], mid[u]);
}
}
}
int ans[N];
void dfs(int u, int fa, int x) { if (fa == -) { //没有父亲结点 向下的最大值就是最大值
d[u] = ;
} else if (mid[fa] == u) {
d[u] = max(x+smx[fa], d[fa]+x);
} else {
d[u] = max(x+mx[fa], d[fa]+x);
}
ans[u] = max(d[u], mx[u]); for (int i = head[u]; ~i; i = edge[i].next) {
int v = edge[i].to;
int c = edge[i].cost;
if (v == fa) continue;
dfs(v, u, c);
}
} int f1[N][], f2[N][];
void init(int n)
{
// f[i,j]表示[i,i+2^j-1]区间最大值
// f[i,j]=max(d[i,j-1], d[i+2^(j-1),j-1])
for (int i = ; i <= n; ++i) f2[i][] = f1[i][] = ans[i];
for (int j = ; (<<j) <= n; ++j)
for (int i = ; i+j- <= n; ++i) {
f1[i][j] = max(f1[i][j-], f1[i+(<<j-)][j-]);
f2[i][j] = min(f2[i][j-], f2[i+(<<j-)][j-]);
}
} int query(int l, int r)
{
int k = ;
while (<<k+ <= r-l+) ++k;
return max(f1[l][k], f1[r-(<<k)+][k]) - min(f2[l][k], f2[r-(<<k)+][k]);
} int main() {
int n, m;
while (~scanf("%d%d", &n, &m) && n) {
int u, v, c;
memset(head, -, sizeof head);
cnt_edge = ;
for (int i = ; i < n; ++i) {
scanf("%d%d%d", &u, &v, &c);
add_edge(u, v, c);
add_edge(v, u, c);
}
//10000000 q
dfs(, -);
dfs(, -, );
//for (int i = 1; i <= n; ++i) printf("d[%d]=%d\n", i, ans[i]);
init(n);
while (m--) {
int q; scanf("%d", &q);
int r = ;
int res = ;
for (int i = ; i <= n; ++i) {
while (r <= n && query(i, r) <= q) r++;
res = max(res, r-i);
}
printf("%d\n", res);
}
}
return ;
}

hdu4123-Bob’s Race(树形dp+rmq+尺取)的更多相关文章

  1. 树形DP+RMQ+尺取法 hdu4123

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4123 参考博客:两种解法-树形dp+二分+单调队列(或RMQ)-hdu-4123-Bob’s Race ...

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

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

  3. hdu 4123--Bob’s Race(树形DP+RMQ)

    题目链接 Problem Description Bob wants to hold a race to encourage people to do sports. He has got troub ...

  4. POJ 4003 Bob’s Race && HDU4123 Bob’s Race (dfs+rmq)

    Bob’s Race Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 378   Accepted: 119 Descript ...

  5. HDU-4123-树形dp+rmq+尺取

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

  6. hdu 4123 树形DP+RMQ

    http://acm.hdu.edu.cn/showproblem.php? pid=4123 Problem Description Bob wants to hold a race to enco ...

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

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

  8. POJ 3162 Walking Race 树形DP+线段树

    给出一棵树,编号为1~n,给出数m 漂亮mm连续n天锻炼身体,每天会以节点i为起点,走到离i最远距离的节点 走了n天之后,mm想到知道自己这n天的锻炼效果 于是mm把这n天每一天走的距离记录在一起,成 ...

  9. POJ - 3162 Walking Race 树形dp 单调队列

    POJ - 3162Walking Race 题目大意:有n个训练点,第i天就选择第i个训练点为起点跑到最远距离的点,然后连续的几天里如果最远距离的最大值和最小值的差距不超过m就可以作为观测区间,问这 ...

随机推荐

  1. android 使用Activity做窗口弹出(模拟Dialog)

    我们下面使用Activity,模拟一个dialog: 首先看布局: <?xml version="1.0" encoding="utf-8"?> & ...

  2. maven3常用命令\创建Project

    转自 http://blog.csdn.net/edward0830ly/article/details/8748986 ------------------------------maven3常用命 ...

  3. 李洪强iOS开发之宏定义方法来初始化一个单例对象

    单例的使用: .m 为了方便实用,只要将以下代码定义在header文件或者.pch文件即可: // .h #define singleton_interface(class) + (instancet ...

  4. java,<E>什么意思?

    泛型 就是指任意类型 比如 HashMap<K,V> 你用的时候 你可以将K,V 设置成任意类 HashMap<String,Integer> K,V 和那个E 一样 Hash ...

  5. inflate方法与findViewById的区别

    LayoutInflater作用是将layout的xml布局文件实例化为View类对象. 对于一个没有被载入或者想要动态载入的界面,都需要使用LayoutInflater.inflate()来找 re ...

  6. 对C#中的web访问mysql数据库的一些知识点进行了整理归纳总结

    基本对比 使用方式 使用场合 优缺点 是否需要安装 需要的dll网址 引用方式 程序内引用 程序初期确定使用MySql,前期添加引用 大多数情况下使用在类文件内,多数使用于aspx,ashx等带有后置 ...

  7. ActiveMQ可靠性机制

    消息的签收(Acknowledgment): 客户端成功接收一条消息的标志是这条消息被签收. 成功接收一条消息一般包括如下三个阶段: (1) 客户端接收消息  (2) 客户端处理消息   (3) 消息 ...

  8. php修改排序,上移下移

    php修改排序,上移下移 /**    $UpDown //移动方向,up或down    $table //表名    $id //当前移动的ID    $id_col //ID字段的名称    $ ...

  9. NFC(12)使用Android Beam技术传输文本数据及它是什么

    Android Beam技术是什么 Android Beam的基本理念就是两部(只能是1对1,不可像蓝牙那样1对多)NFC设备靠近时(一般是背靠背),通过触摸一部NFC设备的屏幕,将数据推向另外一部N ...

  10. C# winform DataGridView

    C# DataGridView控件动态添加新行 DataGridView控件在实际应用中非常实用,特别需要表格显示数据时.可以静态绑定数据源,这样就自动为DataGridView控件添加相应的行.假如 ...