题意 :  一棵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 ;
}

最新文章

  1. iOS 疑难杂症 — — UITableView 添加 tableFooterView 旋转屏幕后收不到点击事件!!!
  2. AutoCAD Civil 3D 中缓和曲线的定义
  3. iOS学习之block
  4. Nodejs学习笔记(一)——初识Nodejs
  5. [麦先生]TP3.2之微信开发那点事[基础篇](微信支付签名算法)
  6. ps、grep和kill联合使用杀掉进程
  7. 用于dbnull的数据转换。因为用convert.to无法转换dbnull类型
  8. 对Jena的简单理解和一个例子
  9. laravel各种路径的获取方法
  10. 通过GitHub和Hexo搭建个人博客
  11. .Net页面缓存OutPutCachexian详解
  12. python基础-------模块与包(三)正则表达式
  13. python pandas 合并数据函数merge join concat combine_first 区分
  14. YML(1)什么是 YML
  15. Scrum Meeting 博客
  16. 开发常用的 Android 函数库
  17. python---循环双向链表实现
  18. i3wm菜单
  19. P3512 [POI2010]PIL-Pilots
  20. C#中DateTime的缺陷 ---- 代替品DateTimeOffset

热门文章

  1. iframe子夜页面调父页面的方法 取父页面的值
  2. HDU 1577 WisKey的眼神 (找规律 数学)
  3. 127.0.0.1、localhost、0.0.0.0的区别
  4. Mac 10.9x下安装配置phonegap3.0开发环境 (涉及android sdk配置)
  5. webgote的例子(6)SQL注入(盲注)
  6. Linux内核中的常用宏container_of其实很简单【转】
  7. linux内核数据结构之链表【转】
  8. dm368 ipnc3.0环境搭建脚本
  9. juery给所有ID属性相同的div绑定一个事件
  10. python不可以打印.doc文件