answer
Consider the formula of it, because there is only one formula related with the second tree, so we can consider the previous formula into with the $ \ text {lca} $ does not matter, that is, $ \ frac {1} {2} (dp_u + dp_v + dis (u, v)) $. Thus we can use the edge of the partition, each point on both sides of the dyed black and white, the virtual configuration tree, then do $ \ text {dp} $ can. It is noted here $ \ text {lca} $ to $ O (1) $ request, the virtual configuration tree sorting process can not, so we can start in accordance with good dfs second sorting tree, then go to partition. Efficiency: $ O (nlogn) $.
Code
#include <bits/stdc++.h> #define LL long long using namespace std; const int N=4e5+5,N2=N<<1,N4=N<<2; int n,m,t=1,fa[22][N2],Lg[N2],d[N],e[N],o,rt,su,hd[N2],sz[N2]; int V[N4],W[N4],nx[N4],b[N],id[N],col[N],tp,S[N],h[2][N],c; LL dp[N],Dp[N],sm[N],f[2][N],ans=-2e18; bool vis[N2];vector<int>X[N],Y[N]; void Add(int u,int v,int w){ X[u].push_back(v);Y[u].push_back(w); } void add(int u,int v,int w){ nx[++t]=hd[u];V[hd[u]=t]=v;W[t]=w; } void add(int u,int v){X[u].push_back(v);} void rebuild(int u,int fr){ int x=0,z=X[u].size(); for (int v,w,i=0;i<z;i++){ v=X[u][i];w=Y[u][i]; if (v==fr) continue;dp[v]=dp[u]+w; if (!x) add(u,v,w),add(v,u,w),x=u; else m++,add(x,m,0),add(m,x,0), add(m,v,w),add(v,m,w),x=m; rebuild(v,u); } } void dfs(int u,int fr){ int z=X[u].size(); fa[0][e[u]=++c]=u;b[id[u]=++t]=u; for (int v,w,i=0;i<z;i++){ v=X[u][i];w=Y[u][i]; if (v==fr) continue; Dp[v]=Dp[u]+w;d[v]=d[u]+1; dfs(v,u);fa[0][++c]=u; } } you're on ( you and, you v) { return d [u] <d [v]? and: v;} you qry ( you have to, you r) { l=e[l];r=e[r]; if (l>r) swap(l,r);int i=Lg[r-l+1]; return Min(fa[i][l],fa[i][r-(1<<i)+1]); } void Sz ( you and, you fr) { sz[u]=1; for (int v,i=hd[u];i;i=nx[i]) if (!vis[i>>1] && (v=V[i])!=fr) S (v, u), s [u] + = s [v]; } void Rt(int u,int fr){ for (int v,w,i=hd[u];i;i=nx[i]) if (!vis[i>>1] && (v=V[i])!=fr){ w=max(sz[v],o-sz[v]); if (w<su) rt=i,su=w;Rt(v,u); } } void find(int u,int fr,LL w,int cl){ if (u<=n) col[u]=cl,sm[u]=w; for (int v,i=hd[u];i;i=nx[i]) if (!vis[i>>1] && (v=V[i])!=fr) find(V[i],u,w+W[i],cl); } void ins(int u){ if (tp<1){S[++tp]=u;return;} int x=qry(S[tp],u); if (x==S[tp]){S[++tp]=u;return;} while(tp>1 && id[S[tp-1]]>=id[x]) add(S[tp-1],S[tp]),tp--; if (x!=S[tp]) add(x,S[tp]),S[tp]=x; S[++tp]=u; } void get(int u){ int z=X[u].size(); f[0][u]=f[1][u]=-2e18; if (~col[u]) f[col[u]][u]=dp[u]+sm[u]; for (int v,i=0;i<z;i++){ v=X[u][i];get(v); for (int j=0;j<2;j++) ans=max(ans,f[j][u]+f[!j][v]-2ll*Dp[u]); for (int j=0;j<2;j++) f[j][u]=max(f[j][u],f[j][v]); } X[u].clear(); } void Solve ( you and, you to, you r) { S (u, 0 ) o = s [i]; rt = 0 ; = the 1E9; Rt(u,0);if (!rt) return; int x=V[rt],y=V[rt^1];vis[rt>>1]=1; find(x,y,0,0);find(y,x,W[rt],1); if (b[l]!=1) ins(1); for (int i=l;i<=r;i++) ins(b[i]); while(tp>1) add(S[tp-1],S[tp]),tp--; tp=0;get(1);int v[2]={0}; for (int w,i=l;i<=r;i++) w=col[b[i]],h[w][++v[w]]=b[i],col[b[i]]=-1; for (int i=0;i<v[0];i++) b[i+l]=h[0][i+1]; for (int i=0;i<v[1];i++) b[r-i]=h[1][v[1]-i]; solve(x,l,l+v[0]-1);solve(y,r-v[1]+1,r); } int main () { cin>>n;m=n; for (int i=1,x,y,z;i<n;i++) scanf("%d%d%d",&x,&y,&z), Add(x,y,z),Add(y,x,z);rebuild(1,0); for (int i=1;i<=n;i++) X[i].clear(),Y[i].clear(),col[i]=-1;t=0; for (int i=1,x,y,z;i<n;i++) scanf("%d%d%d",&x,&y,&z), Add(x,y,z),Add(y,x,z);dfs(1,0); for (int i=2;i<=c;i++) Lg[i]=Lg[i>>1]+1; for (int i=c;i;i--) for (int j=1;i+(1<<j)<=c+1;j++) fa[j][i]=Min(fa[j-1][i],fa[j-1][i+(1<<(j-1))]); for (int i=1;i<=n;i++) X[i].clear(); solve(1,1,n);ans>>=1; for (int i=1;i<=n;i++) ans=max(ans,dp[i]-Dp[i]); cout<<ans<<endl;return 0; }