Topic Links:
http://acm.hdu.edu.cn/showproblem.php?pid=5293
Test instructions
To give you some chain, each chain has its own value, to find the non-overlapping chain can be composed of the maximum value.
Exercises
Tree-shaped DP,
For each chain u,v,w, we only process it at the apex of the LCA (U,V)
Let Dp[i] indicate the maximum value of the exponent with the root of I, Sum[i] the and (vi is the Sons of I) that represent DP[VI]
There are two decisions in point I, one is not to choose the chain with I as LCA, then Dp[i]=sum[i].
The other is to choose a chain with I as the LCA, then there is the transfer equation: Dp[i]=sigma (dp[vj]) +sigma (sum[kj]) +w. (sigma means accumulation, VJ means children who are not on the chain, KJ means children in the chain)
For ease of calculation, we deal with Dp[i]=sum[i]-sigma (Dp[k]-sum[k]) +w=sum[i]+sigma (Sum[k]-dp[k]) +w.
Sigma (Sum[k]-dp[k]) can be calculated logn using the DFS sequence and array arrays.
#pragmaComment (linker, "/stack:1024000000,1024000000")#include<algorithm>#include<iostream>#include<cstring>#include<cstdio>#include<vector>using namespacestd;Const intMAXN =202020;Const intmaxb= A;structNode {intu, V, W; Node (intUintVintW): U (U), V (v), W (w) {}};intN, M;vector<Node>Que[maxn];vector<int>G[MAXN];intLCA[MAXN][MAXB],inch[MAXN], out[maxn],dep[maxn],dfs_cnt;intSUMV[MAXN];intDP[MAXN],SUM[MAXN];//compute the DFS sequence, in,out; pre-processing the ancestor of each order Lca[i][j], representing the first 2^j ancestors, Lca[i][0] representing the FathervoidDfsintUintFaintd) {inch[U] = + +dfs_cnt; lca[u][0] = FA; Dep[u] =D; for(intj =1; J < Maxb; J + +) { intf = lca[u][j-1]; LCA[U][J]= Lca[f][j-1]; } for(inti =0; I < g[u].size (); i++) { intv =G[u][i]; if(v = = FA)Continue; DFS (V, u, D+1); } out[U] = + +dfs_cnt;}//online Lca,o (N*LOGN) preprocessing +o (LOGN) InquiryintLCA (intUintv) {if(Dep[u] <Dep[v]) Swap (U, v); //Binary multiplication method, u,v refers to the same height for(inti = MAXB-1; I >=0; i--) { if(Dep[lca[u][i]] >= dep[v]) u =Lca[u][i]; } //when the LCA is U or v if(U = = v)returnu; //LCA is not a condition of u nor v//go up together. for(inti = MAXB-1; I >=0; i--) { if(Lca[u][i]! =Lca[v][i]) {u=Lca[u][i]; V=Lca[v][i]; } } returnlca[u][0];}//tree-like arrayintGet_sum (intx) {intRET =0; while(X >0) {ret+=Sumv[x]; X-= x& (-x); } returnret;}voidAddintXintv) { while(X <MAXN) {Sumv[x]+=v; X+ = x& (-x); }}//Tree DP (use DFS sequence and tree array to calculate chain quickly)//The idea of a DFS sequence + tree array can draw pictures of itself on paper,voidSolveintUintFA) { for(inti =0; I < g[u].size (); i++) { intv =G[u][i]; if(v = = FA)Continue; Solve (V, u); Sum[u]+=Dp[v]; } Dp[u]=Sum[u]; for(inti =0; I < que[u].size (); i++) {Node& nd =Que[u][i]; //get_sum (in[nd.u]) deals with all the vertices of the path of the LCA (U,V) to the U point//get_sum (OUT[ND.V]) deals with all the vertices of the path of the LCA (U,V) to the V-pointDp[u] = max (Dp[u], Sum[u] + get_sum (inch[nd.u]) + get_sum (inch[ND.V]) +ND.W); } Add (inch[u], Sum[u]-Dp[u]); Add ( out[u], Dp[u]-sum[u]);}voidinit () {dfs_cnt=0; for(inti =1; I <= N; i++) g[i].clear (); for(inti =1; I <= N; i++) que[i].clear (); memset (LCA,0,sizeof(LCA)); memset (SUMV,0,sizeof(SUMV)); memset (SUM,0,sizeof(sum)); Memset (DP,0,sizeof(DP));}intMain () {intTC; scanf ("%d", &TC); while(tc--) {scanf ("%d%d", &n, &m); Init (); for(inti =1; I < n; i++) { intu, v; scanf ("%d%d", &u, &v); G[u].push_back (v); G[v].push_back (U); } DFS (1,0,1); while(m--) { intu, V, W; scanf ("%d%d%d", &u, &v, &W); //each chain is processed at the LCA location so that it is compliant with DP's no-effectQue[lca (U, v)].push_back (Node (U, V, W)); } Solve (1,0); printf ("%d\n", dp[1]); } return 0;}/*1111 (1) 2 3, 1 2, 3 1 , and more.*/
HDU 5293 tree chain problem dp+dfs sequence + tree-like array +lca