Test instructions
Given the number of chains on a tree and the weights of each chain, the maximum weight of a chain that does not contain a common node can be fetched ....
Solution
Pre-treatment of each chain of LCA
Tree DP, D[i] indicates the maximum value that can be obtained when the node is taken, Sum[i]=sigma (D[k] | K is a child of I)
If you do not take I d[i]=sum[i]
If I is taken, E is the chain of LCA for I then D[i]=max (D[i],e's weight +sigma (sum[k])-sigma (D[k])) K is the point on the tree chain
You can use tree chain to split + tree-mounted array to find the value of the chain within the time complexity of NLOGN
Tree chain problem
Time limit:6000/3000 MS (java/others) Memory limit:65536/65536 K (java/others)
Total submission (s): 430 Accepted Submission (s): 114
Problem Descriptioncoco has a tree, whose vertices is conveniently labeled by,..., N.
There is m chain on the tree and each chain have a certain weight. Coco would like to pick out some chains any of the which does not share common vertices.
Find out the maximum sum of the weight Coco can pick
Inputthe input consists of several test cases. The first line of input gives the number of test cases T (t<=10).
For each tests:
First line, positive integers n, m. (1<=n,m<=100000)
The following (n-1) lines contain 2 integers ai bi denoting an edge between vertices ai and bi (1≤ai,bi≤n),
Next m lines each three numbers u, V and Val (1≤u,v≤n,0<val<1000), represent the end points and the weight of a T REE chain.
Outputfor each tests:
A single integer, the maximum number of paths.
Sample Input
17 31 21 32 42 53 63 72 3 44 5 36 7 3
Sample Output
6Hint
Authorfzuacm
Source2015 multi-university Training Contest 1
Recommendwe carefully selected several similar problems for you:5299 5298 5297 5295 5294
/* ***********************************************author:ckbosscreated time:2015 July 22 Wednesday 15:46 03 seconds file Name : hdoj5293.cpp************************************************ * * #include <iostream> #include <cstdio># Include <cstring> #include <algorithm> #include <string> #include <cmath> #include <cstdlib > #include <vector> #include <queue> #include <set> #include <map> #pragma comment (linker, "/ stack:1024000000,1024000000 ") using namespace Std;const int Maxn=100100;int n,m;/**********************chain******** /struct chain{int From,to,weight;} chain[maxn];///chain LCA at POS ivector<int> vi[maxn];/**********************edge*************************/ struct Edge{int to,next;} Edge[maxn*2];int adj[maxn],size;void init () {memset (adj,-1,sizeof (ADJ)); size=0;for (int i=0;i<=n;i++) vi[i].clear ();} void Add_edge (int u,int v) {Edge[size].to=v;edge[size].next=adj[u]; adj[u]=size++;} /**********************lca***/const int deg=22;int fa[maxn][deg];///fa[i][j]i node 2^j ancestor int deg[maxn];///depth void BFS (int Root) {queue<int> Q;deg[root]=0;fa[root][0]=root;q.push (Root), while (!q.empty ()) {int U=q.front (), Q.pop (); for (int i=1;i<deg;i++) {fa[u][i]=fa[fa[u][i-1]][i-1];} for (int i=adj[u];~i;i=edge[i].next) {int v=edge[i].to;if (v==fa[u][0]) Continue;deg[v]=deg[u]+1;fa[v][0]=u;q.push (v );}}} int LCA (int u,int v) {if (Deg[u]>deg[v]) swap (U,V); int hu=deg[u],hv=deg[v];int tu=u,tv=v;for (int det=hv-hu,i=0;det;i ++,DET=DET/2) if (det&1) tv=fa[tv][i];if (TU==TV) return tu;for (int i=deg-1;i>=0;i--) {if (Fa[tu][i]==fa[tv][i]) Continue;tu=fa[tu][i];tv=fa[tv][i];} return fa[tu][0];} /************************ tree chain split ******************/int fa[maxn],deep[maxn],num[maxn],son[maxn];int TOP[MAXN],P[MAXN ],rp[maxn],pos;int tree1[maxn],tree2[maxn];int ans;void init () {init ();p Os=1; Ans=0;memset (son,-1,sizeof (son)); Memset (Tree1,0,sizeof (tree1)); Memset (Tree2,0,sizeof (Tree2));} void dfs1 (int u,int pre,int d) {num[U]=1; Fa[u]=pre; deep[u]=d;for (int i=adj[u];~i;i=edge[i].next) {int v=edge[i].to;if (v==pre) CONTINUE;DFS1 (v,u,d+1); num[u]+=num[v]; if ((son[u]==-1) | | | (Num[son[u]]<num[v])) Son[u]=v;}} void GetPOS (int u,int to) {top[u]=to; p[u]=pos++, Rp[p[u]]=u;if (son[u]!=-1) GetPOS (son[u],to); for (int i=adj[u];~i;i= Edge[i].next) {int v=edge[i].to;if (V!=fa[u]&&v!=son[u]) GetPOS (V,V);}} arrayinline int lowbit (int x) {return x& (-X);} void Add (int* tree,int P,int v) {for (int i=p;i<maxn;i+=lowbit (i)) tree[i]+=v;} int _sum (int* tree,int p) {int sum=0;for (int i=p;i;i-=lowbit (i)) Sum+=tree[i];return sum;} int Query (int* tree,int l,int R) {return _sum (tree,r)-_sum (TREE,L-1);} Query sum of node on the chainint get_chain_sum (int u,int v) {int f1=top[u],f2=top[v];//ret1:sum of sum tree1//Ret2: Sum of D tree2int ret1=0,ret2=0;while (F1!=F2) {if (Deep[f1]<deep[f2]) {swap (F1,F2); swap (u,v);} Ret+=ret1+=query (Tree1,p[f1],p[u]); Ret2+=query (Tree2,p[f1],p[u]); U=FA[F1]; F1=top[u];} if (Deep[u]>deep[v])Swap (U,V);//ret+=ret1+=query (Tree1,p[u],p[v]); Ret2+=query (Tree2,p[u],p[v]); return Ret1-ret2;} Add one point on the node of the chainvoid update (int* tree,int X,int v) {Add (tree,p[x],v);} int d[maxn],sum[maxn];void DFS (int u,int fa) {sum[u]=0;for (int i=adj[u];~i;i=edge[i].next) {int v=edge[i].to;if (V==FA) Continue;dfs (V,u); sum[u]+=d[v];} Not choose U;d[u]=sum[u];update (Tree1,u,sum[u]);///Choose ufor (int i=0,sz=vi[u].size (); i<sz;i++) {int p=vi[u][ I];int w=chain[p].weight,from=chain[p].from,to=chain[p].to;int temp=w+get_chain_sum (from,to);d [U]=max (D[u],temp) ;} if (Ans<d[u]) ans=d[u];update (Tree2,u,d[u]);} int main () {//freopen ("In.txt", "R", stdin); Freopen ("OUT.txt", "w", stdout); int t_t;scanf ("%d", &t_t), while (t_t--) {scanf ("%d%d", &n,&m); INIT (); for (int i=0,u,v;i<n-1;i++) {scanf ("%d%d", &u,&v); Add_edge (U,V); Add_edge (v,u);} BFS (1), for (int i=0,u,v,w;i<m;i++) {scanf ("%d%d%d", &u,&v,&w),//chain[i]= (chain) {U,v,w};chain[i]. From=u; Chain[i].to=v; Chain[i].weight=w;int Lca=lca (u,v); Vi[lca].push_back (i);} DFS1 (1,1,0); GetPOS (;D) FS;p rintf ("%d\n", ans); return 0;}
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Hdoj 5293 tree chain problem lca+ tree chain split + treeview DP