hdu 4123 树的最长路+RMQ
Bob’s Race
Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3034 Accepted Submission(s): 991
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.
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)
1 2 3
2 3 4
4 5 3
3 4 2
1
2
3
4
5
0 0
3
3
3
5
树的最长路:
用搜索的方法求某个点的最远的点的距离了,就是先对任意一个点求距离其最远的顶点,最后可以得到一条树的直径的两个端点,以这两个端点开始去遍历整棵树,两个端点到每个点的距离较大值就会是这个点在树上能够走的最远距离
/*
hdu4123
给你n个点,被n-1条边连着,求出以他们每个点为起点的最长路(不可重复走),
然后是m个查询,找出它们的最长连续串max-min<q
树的最长路 + RMQ
hhh-2016-01-31 03:04:55
*/ #include <functional>
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <Map>
using namespace std;
typedef long long ll;
typedef long double ld; using namespace std; const int maxn = 50005; ll dp1[maxn][20];
ll dp2[maxn][20];
int mm[maxn+5];
ll sum[maxn];
int tot;
int head[maxn]; ll min(ll a,ll b)
{
return a < b ? a:b;
} ll max(ll a,ll b)
{
return a > b ? a:b;
} struct node
{
int to,next;
ll w;
} edge[maxn*2]; void addedge(int u,int v,int w)
{
edge[tot].to = v;
edge[tot].w = w;
edge[tot].next = head[u];
head[u] = tot++;
} void iniRMQ(int n,ll c[])
{
mm[0] = -1;
for(int i = 1; i <= n; i++)
{
mm[i] = ((i&(i-1)) == 0)? mm[i-1]+1:mm[i-1];
dp1[i][0]=dp2[i][0]= c[i];
}
for(int j = 1; j <= mm[n]; j++)
{
for(int i = 1; i+(1<<j)-1 <= n; i++)
{
dp1[i][j] = min(dp1[i][j-1],dp1[i+(1<<(j-1))][j-1]);
dp2[i][j] = max(dp2[i][j-1],dp2[i+(1<<(j-1))][j-1]);
}
}
} ll RMQ(int x,int y)
{
int k = mm[y-x+1];
return (ll)max(dp2[x][k],dp2[y-(1<<k)+1][k])-(ll)min(dp1[x][k],dp1[y-(1<<k)+1][k]);
}
int id;
ll tall; void dfs(int u,int pre,ll cnt) //先找出最远点
{
if(cnt >= tall)
{
id = u;
tall = cnt;
}
for(int i = head[u]; ~i; i = edge[i].next)
{
if(edge[i].to == pre) continue;
dfs(edge[i].to,u,edge[i].w+cnt);
}
} void cal(int u,int pre,ll cnt)
{
for(int i = head[u]; ~i; i = edge[i].next)
{
int v = edge[i].to;
if(v == pre)
continue;
sum[v] = max(sum[v],cnt+edge[i].w);
cal(v,u,cnt+edge[i].w);
}
} int main()
{
int m,n,k;
while(scanf("%d%d",&n,&m) && n && m)
{
int u,v,val;
tot = 0;
memset(head,-1,sizeof(head));
memset(sum,0,sizeof(sum));
for(int i = 1; i < n; i++)
{
scanf("%d%d%d",&u,&v,&val);
addedge(u,v,val);
addedge(v,u,val);
}
tall = 0;
dfs(1,0,0);
cal(id,0,0);
int t = 1;
for(int i = 1;i <= n;i++)
if(sum[i] > sum[t]) t = i;
// printf("%d %d\n",id,t);
cal(t,0,0);
// for(int i = 1;i <= n;i++)
// printf("%d ",sum[i]);
// cout << endl;
iniRMQ(n,sum);
while(m--)
{
scanf("%d",&k);
int ans = 0;
int td = 1;
for(int i = 1;i <= n;i++)
{
while(td <= i && RMQ(td,i) > k) td++;
ans = max(ans,i-td+1);
}
printf("%d\n",ans);
}
}
return 0;
}
hdu 4123 树的最长路+RMQ的更多相关文章
- HDU 2196 Computer (树上最长路)【树形DP】
<题目链接> 题目大意: 输出树上每个点到其它点的最大距离. 解题分析: 下面的做法是将树看成有向图的做法,计算最长路需要考虑几种情况. dp[i][0] : 表示以i为根的子树中的结点与 ...
- 有趣的线段树模板合集(线段树,最短/长路,单调栈,线段树合并,线段树分裂,树上差分,Tarjan-LCA,势能线段树,李超线段树)
线段树分裂 以某个键值为中点将线段树分裂成左右两部分,应该类似Treap的分裂吧(我菜不会Treap).一般应用于区间排序. 方法很简单,就是把分裂之后的两棵树的重复的\(\log\)个节点新建出来, ...
- hihoCoder 1050 树中的最长路 最详细的解题报告
题目来源:树中的最长路 解题思路:枚举每一个点作为转折点t,求出以t为根节点的子树中的‘最长路’以及与‘最长路’不重合的‘次长路’,用这两条路的长度之和去更新答案,最终的答案就是这棵树的最长路长度.只 ...
- 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 树形DP+RMQ
http://acm.hdu.edu.cn/showproblem.php? pid=4123 Problem Description Bob wants to hold a race to enco ...
- HDU 6201 2017沈阳网络赛 树形DP或者SPFA最长路
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6201 题意:给出一棵树,每个点有一个权值,代表商品的售价,树上每一条边上也有一个权值,代表从这条边经过 ...
- hiho #1050 : 树中的最长路 树的直径
#1050 : 树中的最长路 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 上回说到,小Ho得到了一棵二叉树玩具,这个玩具是由小球和木棍连接起来的,而在拆拼它的过程中, ...
- hdu 4638 树状数组 区间内连续区间的个数(尽可能长)
Group Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Subm ...
- HDU 4607 Park Visit (树的最长链)
Park Visit Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
随机推荐
- Mysql数据库的触发程序
/** **创建表 */ CREATE TABLE test1(a1 INT); CREATE TABLE test2(a2 INT); CREATE TABLE test3(a3 INT NOT N ...
- JAVA_SE基础——25.面向对象练习
黑马程序员入学blog ... 昨晚我写了篇面向对象的内存分析,今天我们来做个小练习.. 需求: 使用java描述一个车与修车厂两个事物, 车具备的公共属性:轮子数. 名字. 颜色 ,还 具备跑的功能 ...
- 关于 Ubuntu Linux 16.04中文版的 root 权限及桌面登录问题
新接触 Ubuntu 的朋友大多会因为安装中没有提示设置 root 密码而不太清楚是什么原因. 起初 Ubuntu 团队希望安装尽可能的简单. 不使用 root , 在安装期间的两个用户交互步骤可以省 ...
- Spring Security入门(3-1)Spring Security的登录页面定制
- maven入门(9)Maven常用命令
Maven常用命令 清理 clean编译 compile打包 package安装 install跳过测试 clean package -Dmaven.test.skip=true
- 数据结构与算法 —— 链表linked list(03)
继续关于linked list的算法题: 删除排序链表中的重复元素 给定一个排序链表,删除所有重复的元素使得每个元素只留下一个. 案例: 给定 1->1->2,返回 1->2 给定 ...
- 真正理解拉格朗日乘子法和 KKT 条件
这篇博文中直观上讲解了拉格朗日乘子法和 KKT 条件,对偶问题等内容. 首先从无约束的优化问题讲起,一般就是要使一个表达式取到最小值: \[min \quad f(x)\] 如 ...
- cache和buffer
一.free命令是Linux查看内存使用情况的命令 1. centos 7风格 [root@bogon init.d]# free -m total used free shared buff/cac ...
- hdu 1880 魔咒字典
https://vjudge.net/problem/HDU-1880 题意:略 思路: 一开始就是想到了正确的思路,但是代码写炸了,死活过不了.这题嘛,就是建议一个魔咒与咒语的双向映射.首先用字符串 ...
- POJ-2923 Relocation---01背包+状态压缩
题目链接: https://vjudge.net/problem/POJ-2923 题目大意: 有n个货物,给出每个货物的重量,每次用容量为c1,c2的火车运输,问最少需要运送多少次可以将货物运完 思 ...