Noip data good water, at first there are several wrong results Noip data on the water??
"The main topic"
The diameter of the root-free tree does not exceed the length of s long chain, so that the eccentric distance is minimal. The specific concept is shown in the original question.
Ideas
First clarify several properties:
(1) For any point in the tree, the farthest points must be at one end of the tree's diameter.
(2) All diameters are equivalent, that is, any one can find the minimum eccentricity equal.
So we can use Dfs two times to find the diameter. Take one point to find the furthest point R, and then from R find the point L farthest from it. The path from L to R is the diameter.
It is clear that the longest chain is the best in cases where the length does not exceed S. Maintain a chain as long as possible on L to R, finding the minimum value of the left and right end points to the larger values of the diameter. It then starts at each point in the chain and finds the maximum depth of other points that do not pass through the points on the diameter. The larger of this maximum depth and the previous minimum value is the answer.
Why is the maximum depth of the entire diameter not found on the core?
Obviously, if the deepest point of the depth is not from the point in the nucleus, then its distance to the nucleus must be less than the distance from the core's endpoint to the diameter endpoint. So if a node-to-nucleus distance is less than the distance from the core's endpoint to the diameter endpoint, it must have been extended from the nucleus.
"Error Point"
See procedure in detail.
1#include <bits/stdc++.h>2 using namespacestd;3 Const intmaxn=500000+ -;4 Const intinf=0x7fffffff;5 structEdge6 {7 intTo,len;8 };9Vector<edge>E[MAXN];Ten intn,s; One intL,R,DIS[MAXN],F[MAXN],BAN[MAXN]; A - voidAddedge (intUintVintW) - { the E[u].push_back (Edge) {v,w}); - E[v].push_back (Edge) {u,w}); - } - + voidInit () - { +scanf"%d%d",&n,&s); A for(intI=1; i<n;i++) at { - intu,v,w; -scanf"%d%d%d",&u,&v,&W); - Addedge (u,v,w); - } - } in - voidDfsintUintFA) to { +f[u]=FA; - for(intI=0; I<e[u].size (); i++) the { * intto=e[u][i].to; $ if(Ban[to] | | to==f[u])Continue;Panax Notoginsengdis[to]=dis[u]+E[u][i].len; - DFS (to,u); the } + } A the voidgetd () + { -memset (Ban,0,sizeof(ban)); $ $L=1, r=1; -DFS (L,0); - for(intI=1; i<=n;i++)if(Dis[i]>dis[r]) r=i; the -L=R;Wuyidis[r]=0; theDFS (R,0); - for(intI=1; i<=n;i++)if(Dis[i]>dis[l]) l=i; Wu } - About voidSolve () $ { - inti=l,j=l,ans=INF; - for(; i;i=F[i]) - { A while(F[j] && dis[i]-dis[f[j]]<=s) j=F[j]; +Ans=min (Ans,max (dis[j],dis[l]-dis[i])); the //every time I find a chain that is closest to S for an endpoint - //compare lengths of end points and diameter ends $ } the for(I=l;i;i=f[i]) ban[i]=1; the //to find the maximum depth without passing through the diameter, it is forbidden to access points on the diameter the for(intI=l;i;i=f[i]) dis[i]=0, DFS (I,f[i]); the //★★★★★★★ Note that the father of I must pass in the f[i], otherwise it will modify the diameter - for(intI=1; i<=n;i++) ans=Max (ans,dis[i]); inprintf"%d", ans); the } the About intMain () the { the init (); the getd (); + solve (); - return 0; the}
"Dfs Good question" bzoj1999-[kernel of Noip2007]core Tree Network (data-enhanced version)