博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HDU 4123(树上任意点到其他点的最远距离,rmq
阅读量:4314 次
发布时间:2019-06-06

本文共 2383 字,大约阅读时间需要 7 分钟。

题目:求出一棵树上任意一点能到的最远距离,然后若干询问,问区间内最大最小距离只差小于q的区间最长有多长。

思路:最远距离通过两次dfs树形dp求得,询问需要先用st表处理一下,然后线性扫。基本是参考kuangbin的。

ps:可能是我写挫了。。用vector做邻接表是1996ms过了一次,然后就是无限tle。。。。不得不改成手写链表才搞到1500ms。。。vector感觉不能随便用了啊。。。。。。

http://www.cnblogs.com/kuangbin/archive/2013/11/08/3414812.html

#include 
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define pb push_back#define fs first#define se second#define sq(x) (x)*(x)#define eps 0.0000000001#define IINF (1<<30)#define clr(x) memset((x),0,sizeof (x))using namespace std;typedef long long ll;typedef pair
P;const int maxv=5e4+300;int N,M;struct EDGE{ int t,d; EDGE *nt;}pool[maxv*3];int ph=0;EDGE *newedge(){ pool[ph].nt=NULL; return &pool[ph++];}EDGE *head[maxv],*tail[maxv];int maxd[maxv],maxdn[maxv],smaxd[maxv],smaxdn[maxv];void addedge(int x,int y,int z){ tail[x]->nt=newedge(); tail[x]=tail[x]->nt; tail[x]->t=y,tail[x]->d=z;}void dfs1(int v,int fa){ for(EDGE *i=head[v]->nt;i!=NULL;i=i->nt){ int u=i->t; int len=i->d; if(u==fa) continue; dfs1(u,v); if(maxd[u]+len>smaxd[v]){ smaxd[v]=maxd[u]+len; smaxdn[v]=u; if(smaxd[v]>maxd[v]){ swap(smaxd[v],maxd[v]); swap(smaxdn[v],maxdn[v]); } } }}void dfs2(int v,int fa){ for(EDGE *i=head[v]->nt;i!=NULL;i=i->nt){ int u=i->t; int len=i->d; if(u==fa) continue; if(u==maxdn[v]){ if(smaxd[v]+len>smaxd[u]){ smaxd[u]=smaxd[v]+len; smaxdn[u]=v; if(smaxd[u]>maxd[u]){ swap(smaxd[u],maxd[u]); swap(smaxdn[u],maxdn[u]); } } }else{ if(maxd[v]+len>smaxd[u]){ smaxd[u]=maxd[v]+len; smaxdn[u]=v; if(smaxd[u]>maxd[u]){ swap(smaxd[u],maxd[u]); swap(smaxdn[u],maxdn[u]); } } } dfs2(u,v); }}ll STmin[maxv][30];ll STmax[maxv][30];void makeST(){ memset(STmin,0x3f,sizeof STmin); memset(STmax,0,sizeof STmax); for(int i=1;i<=N;i++){ STmin[i][0]=STmax[i][0]=maxd[i]; } for(int k=1;k<25;k++){ for(int i=1;i+(1<
<=N+1;i++){ STmin[i][k]=min(STmin[i][k-1],STmin[i+(1<<(k-1))][k-1]); STmax[i][k]=max(STmax[i][k-1],STmax[i+(1<<(k-1))][k-1]); } }}int getdif(int l,int r){ int k=0; while((1<<(k+1))
nt=NULL; tail[i]=head[i]; }}int main(){ freopen("/home/files/CppFiles/in","r",stdin); /* std::ios::sync_with_stdio(false); std::cin.tie(0);*/ while(cin>>N>>M){ if(N==0&&M==0) break; init(); for(int i=0;i
View Code

 

转载于:https://www.cnblogs.com/Cw-trip/p/4700852.html

你可能感兴趣的文章
扩展 IEnumerable<T>,让它根据另一个集合的顺序来排列
查看>>
mvc4.0添加EF4.0时发生编译时错误
查看>>
第16月第12天 CABasicAnimation 旋转加速
查看>>
Linux下查看Python安装了哪些脚本模块
查看>>
ERROR- 开发常见error
查看>>
Servlet 中文乱码问题及解决方案剖析
查看>>
OO第四次博客总结
查看>>
集合—ArrayList
查看>>
web前台设计技术
查看>>
Ubuntu14.04 在右键中添加 在终端中打开
查看>>
Eclipse代码规范工具-Checkstyle安装和使用
查看>>
【读书笔记】 nginx 负载均衡测试
查看>>
JQUERY1.9学习笔记 之属性选择器(一) 前缀选择器
查看>>
TortoiseSVN显示图标不正常
查看>>
joj1020
查看>>
javascript模式——Decorator
查看>>
junit测试简单实例
查看>>
迷宫问题,POJ-3984
查看>>
python 文件操作的函数
查看>>
【2017下集美大学软工1412班_助教博客】团队作业3——需求改进&系统设计团队成绩公示...
查看>>