1.對於樹中的任意一點,距離其最遠的點一定是樹的直徑的某一端點
2.同一棵樹的直徑的中點相同(題目裏給出來的,雖然不知道怎麼用)
3.要求的一定在直徑上,並且越長越好(不在直徑上的點到端點的距離
4.任意搞一條直徑求出來的偏心距是一樣的
隨意求一條直徑,然後摳出來枚舉頭尾處理一下
當前的這條鏈到別的點中最長的距離爲max(到兩端點的距離,到不在直徑的點的最遠距離)
#include<cstdio>
#include<algorithm>
#include<cstring>
#define N 500000
using namespace std;
struct edge{int to,v,next;}e[N*2+5];
int n,S,cnt,L,R,ans,head[N+5],que[N+5],fa[N+5],dis[N+5],dir[N+5];
inline void add(int x,int y,int z){
e[++cnt]=(edge){y,z,head[x]};head[x]=cnt;
e[++cnt]=(edge){x,z,head[y]};head[y]=cnt;
}
inline void bfs(int x,int opt){
int h=0,t=1;
que[1]=x;memset(dis,-1,sizeof(dis));dis[x]=0;
while(h<=t){
++h;
int u=que[h];
for(int i=head[u];i;i=e[i].next)
if(dis[e[i].to]==-1){
dis[e[i].to]=dis[u]+e[i].v;
if(opt==1) fa[e[i].to]=u;
que[++t]=e[i].to;
}
}
}
void dfs(int x,int f){
for(int i=head[x];i;i=e[i].next)
if(e[i].to!=f&&!dir[e[i].to]){
dis[e[i].to]=dis[x]+e[i].v;
dfs(e[i].to,x);
}
}
int main(){
scanf("%d%d",&n,&S);
for(int i=1,x,y,z;i<n;++i) {
scanf("%d%d%d",&x,&y,&z);
add(x,y,z);
}
L=1;bfs(L,0);for(int i=1;i<=n;++i) L=dis[i]>dis[L]?i:L;
R=L;bfs(L,1);for(int i=1;i<=n;++i) L=dis[i]>dis[L]?i:L;
for(int i=L;i;i=fa[i]) dir[i]=1;
ans=1<<30;
for(int p=L,q=L;p;p=fa[p]){
while(fa[q]&&dis[p]-dis[fa[q]]<=S) q=fa[q];
ans=min(ans,max(dis[q],dis[L]-dis[p]));
}
for(int i=L;i;i=fa[i])
dis[i]=0,dfs(i,fa[i]);
for(int i=1;i<=n;++i) ans=max(ans,dis[i]);
printf("%d\n",ans);
}