您的位置:首页 > 其它

HDU 4123 Bob’s Race (树形DP + 单调队列)

2014-11-17 21:35 369 查看
参考

题意:

给定n个点的带边权树Q个询问。

下面n-1行给出树

设dp[i]表示树上离 i 点最远点的距离

下面Q行每行一个数字表示询问。

询问L, 表示求出 dp 数组中最长的连续子序列使得序列中最大值-最小值 <= L,输出这个序列的长度。

思路:

求dp数组就是求个树的直径然后dfs一下。

接着就和这题一样了。

对于每个询问,可以用一个单调队列维护一下。O(n)的回答。


Bob’s Race

Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 2639    Accepted Submission(s): 840


Problem Description

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.

 

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

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

 

Source

2011 Asia Fuzhou Regional Contest

#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#include <cmath>
using namespace std;
#define ll long long
#define prt(k) ;//cerr<<#k" = "<<k<<endl
const int N = 50050;
const int M = 2 * N;
int n, m;
const ll inf = 0x3f3f3f3f;
int head[M], to[M], next[M], cost[M];
int tot;
void initEdge()
{
tot = 0;
memset(head, -1, sizeof head);
}
void addEdge(int u, int v, int w)
{
to[++tot] = v, cost[tot] = w;
next[tot] = head[u];
head[u] = tot;
}
ll dis
;
int pre
;
int BFS(int x)  ///return farest point from x
{
memset(dis, -1, sizeof dis);
dis[x] = 0;
pre[x] = -1;
int far = x;
queue<int> q;
q.push(x);
while(!q.empty())
{
int u=q.front();q.pop();
for(int i=head[u];~i;i=next[i])
{
int v = to[i];
if(dis[v]==-1)
{
dis[v] = dis[u] + cost[i];
pre[v] = u;
if(dis[far] < dis[v])
far = v;
q.push(v);
}
}
}
return far;
}
ll dp
;
bool vis
;
void dfs(int u)
{
vis[u] = true;
for(int i=head[u];~i;i=next[i])
{
int v = to[i];
if(vis[v]) continue;
dp[v] = dp[u] + cost[i];
dfs(v);
}
}
int stk
;
int len;
void build()    ///预处理树的直径
{
int E = BFS(1);
int S = BFS(E);
int top = 0;
int u = S;
len = dis[S];
memset(vis, 0, sizeof vis);
while(u != -1)
{
stk[top++] = u;
dp[u] = max(dis[u], len - dis[u]);
vis[u] = true;
u = pre[u];
}
for(int i=0;i<top;i++)  dfs(stk[i]);
}
int qMax[M], qMin[M];
int main()
{
//  freopen("in.txt","r",stdin);
while(scanf("%d%d",&n,&m)==2, n+m)
{
initEdge();
for(int i=0;i<n-1;i++)
{
int u,v,w;
scanf("%d%d%d", &u,&v,&w);
addEdge(u,v,w);
addEdge(v,u,w);
}
build();
// for(int i=1;i<=n;i++) printf("dp[%d] = %d\n",i,dp[i]);
while(m--)
{
int v; scanf("%d",&v);
int ans, hmax, tmax, hmin, tmin;
ans=hmax=tmax=hmin=tmin=0;
int st = 0;
tmax=tmin=-1;
for(int i=1;i<=n;i++)
{
while(hmax<=tmax&&dp[qMax[tmax]]<dp[i]) --tmax;
qMax[++tmax] = i;
while(hmin<=tmin&&dp[qMin[tmin]]>dp[i]) --tmin;
qMin[++tmin] = i;
while(dp[qMax[hmax]]-dp[qMin[hmin]] > v)
{
if(qMax[hmax]<=qMin[hmin])
st = qMax[hmax++];
else
st = qMin[hmin++];
}
ans=max(ans, i-st);
}
printf("%d\n", ans);
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: