Test instructions is to give n points of the tree, there will be a link between the M chain two points, calculated that they do not have the maximum value of the public point, the public point when this calculation as long as they have a common point in their LCA chain, they intersect
Dp[i] The maximum value that can be obtained for the subtree contained in this point
Sum[i] Indicates that this point has no option to pass the total value of this point chain
Two options
This point has not been chosen.
Dp[i]=sum[i]=sigma (Dp[k]) K is a subtree of I
A chain was selected
Suppose this chain is (Tyuijk)
Then dp[i]= (Sum[i]-dp[u]-dp[j]) + (Sum[j]-dp[k]) +dp[k] + (Sum[u]-dp[y]) + (sum[y]-dp[t]) +sum[t];
Finishing found Dp[i]=sum[i] + (Sum[j]-dp[j]) + (Sum[k]-dp[k]) + (Sum[u]-dp[u]) + (Sum[y]-dp[y]) + (sum[t]-dp[t]);
Using LCA to calculate the nearest common ancestor of each strand, judging whether the chain is used in this recent public ancestor, and we can use time stamps and tree arrays to find sum and DP
#include <iostream>#include<algorithm>#include<string.h>#include<cstdio>#include<vector>using namespacestd;Const intmaxn=100000+Ten;intto[maxn*2],nx[maxn*2],h[maxn*2],numofedg,timoflook;intfa[maxn][ -],FIRST[MAXN],LAST[MAXN],DEPTH[MAXN];voidADDEDG (intUintv) {NUMOFEDG++; To[numofedg]=v; Nx[numofedg]=h[u]; h[u]=NUMOFEDG; NUMOFEDG++; To[numofedg]=u; NX[NUMOFEDG]=H[V]; h[v]=numofedg;}voidDfsintCurintPerintDEP) {First[cur]=++Timoflook; Depth[cur]=DEP; fa[cur][0]=per; for(intI=1; i< -; i++) {Fa[cur][i]=fa[fa[cur][i-1] [i1 ]; } for(intI=h[cur]; I I=Nx[i]) { if(To[i]==per)Continue; DFS (TO[I],CUR,DEP+1); } Last[cur]=++Timoflook;}intGetlca (intUintv) { if(depth[u]<Depth[v]) swap (U,V); for(intI= +; i>=0; i--) { if(depth[fa[u][i]]>=depth[v]) u=Fa[u][i]; if(U==V)returnu; } for(intI= +; i>=0; i--) { if(fa[u][i]!=Fa[v][i]) {u=Fa[u][i]; V=Fa[v][i]; } } returnfa[u][0];}structedg{intU,v,lca,val;} P[maxn];vector<int>E[MAXN];intdp[maxn],sum[maxn],cs[maxn*3],cd[maxn*3];intLowbit (intx) { returnx&-x;}voidAddintXintDint*b) { while(x<=Timoflook) {C[x]+=E; X+=lowbit (x); }}intGetsum (intXint*C) { intret=0; while(x>0) {ret+=C[x]; X-=lowbit (x); } returnret;}voidSolveintCurintper) {Dp[cur]=sum[cur]=0; for(intI=h[cur]; I I=Nx[i]) { if(To[i]==per)Continue; Solve (to[i],cur); Sum[cur]+=Dp[to[i]]; } Dp[cur]=Sum[cur]; for(intI=0; I<e[cur].size (); i++) { intId=E[cur][i]; intu=p[id].u; intv=p[id].v; intt1=getsum (FIRST[U],CS); intT2=getsum (FIRST[V],CS); intt3=getsum (FIRST[U],CD); intt4=getsum (FIRST[V],CD); inttmp=t1+t2-t3-T4; Dp[cur]=max (dp[cur],tmp+p[id].val+Sum[cur]); } add (First[cur],sum[cur],cs); Add (Last[cur],-Sum[cur],cs); Add (FIRST[CUR],DP[CUR],CD); Add (Last[cur],-dp[cur],cd);}intMain () {intCAs; scanf ("%d",&CAs); for(intCc=1; cc<=cas; Cc++) { intn,m; Timoflook=numofedg=0; scanf ("%d%d",&n,&m); for(intI=0; i<=n; i++) {cs[i*2]=cs[i*2+1]=cd[i*2]=cd[i*2+1]=0; H[i]=0; E[i].clear (); } for(intI=1; i<n; i++) { intu,v; scanf ("%d%d",&u,&v); ADDEDG (U,V); } fa[1][0]=1; DFS (1,1,0); for(intI=0; i<m; i++) {scanf ("%d%d%d",&p[i].u,&p[i].v,&p[i].val); P[i].lca=Getlca (P[I].U,P[I].V); E[p[i].lca].push_back (i); } Solve (1,-1); printf ("%d\n", dp[1]); } return 0;}View Code
hdu5293 lca+dp+ tree-like array + timestamp