首先明确:树上任意一点的最长路径一定是直径的某一端点。
所以先找出直径,求出最长路径,然后再求波动值<=m的最长区间
#include#include #include #include #include #include #include #define N 1000005using namespace std; int fa[N],cal[N],dis[2][N],d[N]; int e=1,head[N]; struct edge{ int u,v,w,next;}ed[N]; void add(int u,int v,int w){ ed[e].u=u; ed[e].v=v; ed[e].w=w; ed[e].next=head[u]; head[u]=e++;} int L,R,it,maxn; bool bo[N]; void dfs(int x,int len){ bo[x]=1; if(len>maxn) it=x,maxn=len; if(!bo[fa[x]]) dfs(fa[x],len+cal[x]); for(int i=head[x];i;i=ed[i].next){ if(!bo[ed[i].v]) dfs(ed[i].v,len+ed[i].w); }} int q[N],h,t; void bfs(int x,int wh){ bo[x]=1;int now,v,w; dis[wh][x]=0; q[1]=x; h=t=1; while(h<=t){ now=q[h++]; if(fa[now]&&!bo[fa[now]]&&dis[wh][fa[now]]