1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #define N 600000 5 using namespace std; 6 int cnt,n,s,head[N],next[N*2],u[N*2],v[N*2],q[N],h,t,d[N],f[N],mx,rt1,mx1,from[N],zhan[N],tot,mark[N]; 7 int l,r,ans; 8 void jia(int a1,int a2,int a3) 9 { 10 cnt++; 11 next[cnt]=head[a1]; 12 head[a1]=cnt; 13 u[cnt]=a2; 14 v[cnt]=a3; 15 return; 16 } 17 bool pan(int a1) 18 { 19 int L=1,R=tot; 20 for(;zhan[1]-zhan[L]<=a1;L++); 21 for(;zhan[R]-zhan[tot]<=a1;R--); 22 if(zhan[L-1]-zhan[R+1]>s) 23 return 0; 24 return 1; 25 } 26 void dfs(int a1) 27 { 28 h=0; 29 t=1; 30 q[t]=a1; 31 memset(f,0,sizeof(f)); 32 f[a1]=1; 33 d[a1]=0; 34 for(;h<t;) 35 { 36 h++; 37 int p=q[h]; 38 for(int i=head[p];i;i=next[i]) 39 if(!f[u[i]]) 40 { 41 if(mark[u[i]]) 42 d[u[i]]=d[p]; 43 else 44 d[u[i]]=d[p]+v[i]; 45 q[++t]=u[i]; 46 from[u[i]]=p; 47 f[u[i]]=1; 48 } 49 } 50 return; 51 } 52 int main() 53 { 54 scanf("%d%d",&n,&s); 55 for(int i=1;i<n;i++) 56 { 57 int a1,a2,a3; 58 scanf("%d%d%d",&a1,&a2,&a3); 59 jia(a1,a2,a3); 60 jia(a2,a1,a3); 61 } 62 dfs(1); 63 mx=1; 64 for(int i=1;i<=n;i++) 65 if(mx<d[i]) 66 { 67 mx=d[i]; 68 rt1=i; 69 } 70 dfs(rt1); 71 mx=0; 72 for(int i=1;i<=n;i++) 73 if(mx<d[i]) 74 { 75 mx=d[i]; 76 mx1=i; 77 } 78 r=d[mx1]; 79 zhan[++tot]=d[mx1]; 80 mark[mx1]=1; 81 for(;mx1!=rt1;) 82 { 83 mx1=from[mx1]; 84 zhan[++tot]=d[mx1]; 85 mark[mx1]=1; 86 } 87 dfs(rt1); 88 for(int i=1;i<=n;i++) 89 if(d[i]>l) 90 l=d[i]; 91 for(;l<=r;) 92 { 93 int mid=(l+r)>>1; 94 if(pan(mid)) 95 { 96 ans=mid; 97 r=mid-1; 98 } 99 else 100 l=mid+1; 101 } 102 printf("%d ",ans); 103 return 0; 104 }
显然最长距离最短,一定是在直径上,我们先DFS两遍找出直径,把直径上的边赋值成0,跑一遍dfs,找一个最大值作为l,二分答案判断。