题意 :  一棵n个节点的树。wc爱跑步,跑n天,第i天从第i个节点开始跑步,每次跑到距第i个节点最远的那个节点(产生了n个距离),现在要在这n个距离里取连续的若干天,使得这些天里最大距离和最小距离的差小于M,问怎么取使得天数最多?

 
每个点的最大距离和之前http://acm.hdu.edu.cn/showproblem.php?pid=2196这道题一样
(就是求每个子树的最长子链,次长子链,然后求经过父亲节点能达到的最大值,比较一下)
 
嗯求最长连续天数这个显然n^2是不现实的,但是连续什么的会想起很久以前似曾相识的一道优先队列题...然后强行一个大根堆一个小根堆,l和r适当情况下右移,复杂度n就可以a了...
 #include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
#define pa pair<long long,int>
const int maxn=;
int n,m;
priority_queue< pa,vector< pa >,less< pa > >q1;
priority_queue< pa,vector< pa >,greater< pa > >q2;
struct nod{
int y;
long long v;
int next;
}e[maxn*];
int vis[maxn]={};
long long f[maxn][]={}; //0父亲 1最长 2次长
long long ma[maxn]={};
int f1[maxn][]={};
int head[maxn]={};
int tot=;
void init(int x,int y,long long v){
e[++tot].y=y;
e[tot].v=v;
e[tot].next=head[x];
head[x]=tot;
}
void dfs(int x){
int y;
vis[x]=;
long long tmp=;
for(int i=head[x];i;i=e[i].next){
y=e[i].y;
tmp=e[i].v;
if(!vis[y]){
dfs(y);
tmp+=f[y][];
if(tmp>f[x][]){
f[x][]=f[x][];
f1[x][]=f1[x][];
f[x][]=tmp;
f1[x][]=y;
}
else if(tmp>f[x][]){
f[x][]=tmp;
f1[x][]=y;
}
}
}
}
void dfs2(int x,int fa,long long v){
int y;
long long tmp;
vis[x]=;
if(f1[fa][]==x){
f[x][]=v+max(f[fa][],f[fa][]);
}
else{
f[x][]=v+max(f[fa][],f[fa][]);
}
ma[x]=max(f[x][],f[x][]);
for(int i=head[x];i;i=e[i].next){
y=e[i].y;
tmp=e[i].v;
if(!vis[y]){
dfs2(y,x,tmp);
}
}
}
long long mab(long long x){
if(x<){
return -x;
}
return x;
}
int main(){
scanf("%d%d",&n,&m);
int y;
long long v;
for(int i=;i<n;i++){
scanf("%d%lld",&y,&v);
init(i+,y,v);
init(y,i+,v);
}dfs();
memset(vis,,sizeof(vis));
dfs2(,,);
int ans=;
int l=,r=;
for(int i=;i<=n;i++){
q1.push(make_pair(ma[i],i));
q2.push(make_pair(ma[i],i));
r++;
int id1=q1.top().second,id2=q2.top().second;
while(id1<l){
q1.pop();
id1=q1.top().second;
}
while(id2<l){
q2.pop();
id2=q2.top().second;
}
long long z1=q1.top().first,z2=q2.top().first;
while(mab(z1-z2)>=m){
l++;
while(id1<l){
q1.pop();
id1=q1.top().second;
}
while(id2<l){
q2.pop();
id2=q2.top().second;
}
z1=q1.top().first,z2=q2.top().first;
}ans=max(ans,r-l+);
}
cout<<ans<<endl;
return ;
}

POJ 3162 Walking Race 树形dp 优先队列的更多相关文章

  1. POJ 3162.Walking Race 树形dp 树的直径

    Walking Race Time Limit: 10000MS   Memory Limit: 131072K Total Submissions: 4123   Accepted: 1029 Ca ...

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

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

  3. 【题解】poj 3162 Walking Race 树形dp

    题目描述 Walking RaceTime Limit: 10000MS Memory Limit: 131072KTotal Submissions: 4941 Accepted: 1252Case ...

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

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

  5. POJ 3162 Walking Race(树形dp+单调队列 or 线段树)

    http://poj.org/problem?id=3162 题意:一棵n个节点的树.有一个屌丝爱跑步,跑n天,第i天从第i个节点开始跑步,每次跑到距第i个节点最远的那个节点(产生了n个距离),现在要 ...

  6. 【POJ3162】Walking Race 树形dp+单调队列+双指针

    题目大意:给定一棵 N 个节点的无根树,边有边权,现生成一个序列 d,d[i] 表示 i 号节点到树上其他节点距离的最大值.给定一个 m,求 d 序列中最大值和最小值之差不超过 m 的最长连续段的长度 ...

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

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

  8. POJ 3162 Walking Race (树的直径,单调队列)

    题意:给定一棵带边权的n个节点的树,首先要求出每个点的最长路,然后写成序列d[1],d[2]...d[n],然后求满足 区间最大值-区间最小值<=k 的最大区间长度为多少? 思路: 分两步进行: ...

  9. poj 2324 Anniversary party(树形DP)

    /*poj 2324 Anniversary party(树形DP) ---用dp[i][1]表示以i为根的子树节点i要去的最大欢乐值,用dp[i][0]表示以i为根节点的子树i不去时的最大欢乐值, ...

随机推荐

  1. 微信小程序开发(三)项目目录及文件结构

    第二章我们已经创建了一个Hello WXapplet示例小程序.我们从文件目录结构来了解Hello WXapplet项目的构成. 目录结构显示,在小程序项目的根目录下面包含3个app开头的文件(app ...

  2. Broken Necklace

    Description 你有一条由N个红色的,白色的,或蓝色的珠子组成的项链(3<=N<=350),珠子是随意安排的. 这里是 n=29 的二个 例子: 1 2 1 2 r b b r b ...

  3. CodeForces - 1004C

    Since Sonya is interested in robotics too, she decided to construct robots that will read and recogn ...

  4. h5 canvas动画,不知道谁写的

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  5. 2017ACM暑期多校联合训练 - Team 8 1011 HDU 6143 Killer Names (容斥+排列组合,dp+整数快速幂)

    题目链接 Problem Description Galen Marek, codenamed Starkiller, was a male Human apprentice of the Sith ...

  6. RMQ之ST求区间最大值

    题目链接:https://cn.vjudge.net/problem/HRBUST-1188 每一次按照二进制的方式进行更新,二维数组dp [i] [j],i表示下标,j表示从i 开始的往后移动2的j ...

  7. Xcode 9安装

    Xcode 9 Xcode 9 Compatibility Xcode 9 requires a Mac running macOS 10.13.2 or later. Xcode 9 include ...

  8. SurfaceFlinger 讲解

    SurfaceFlinger是Android multimedia的一个部分,在Android 的实现中它是一个service,提供系统 范围内的surface composer功能,它能够将各种应用 ...

  9. C/C++——#和##操作符

    1. #操作符 使用阶段:预处理阶段,只有宏定义中使用(#define) 作用:将宏参数转换为字符串 示例: #define STRING(x) #x 2. ##操作符 使用阶段:预处理阶段,只有宏定 ...

  10. YAML中使用Jinja模板以{{ foo }}开头需要整行加双引号

    YAML陷阱 YAML语法要求如果值以{{ foo }}开头的话我们需要将整行用双引号包起来.这是为了确认你不是想声明一个YAML字典.该知识点在 YAML 语法 页面有所讲述. 这样是不行的: - ...