Topic Link: [Click to enter] (http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=13013)
Tree chain is not a complex algorithm or data structure, but can be a tree broken into a chain to deal with, in other words, the tree chain is just XXX data structure/algorithm in the promotion of trees, or, the tree chain is just the tree hash to a few successive intervals. For example, the following problem, is to divide the tree into heavy chain and light chain and then map to the line segment tree, and then in the segment tree to query and modify operations. So the focus of the tree chain is two, one is the correct decomposition of the tree into a few paragraphs and mapped to the line segment tree, the second is in the line tree in the query and modify the operation should pay attention to the nature of the tree after decomposition.
The following code is for a query to modify the edges on the tree and can be used as a template.
A very good blog: Tree chain split
The code is as follows:
#include <iostream>#include <cstdio>#include <cstring>usingnamespace Std;/// Modify a single edge based on edge rights/// query path edge weight MaxConst intmaxn=10010;structedge{intTo,next;} edge[maxn*2];intHead[maxn],tot;intTOP[MAXN];/// Top[v] represents the top node of the V chainintFA[MAXN];// parent NodeintDEEP[MAXN];// DepthintNUM[MAXN];/// Num[v] Represents a node tree of a subtree rooted in VintP[MAXN]; ///P[V] represents the position of V with its parent node in the segment treeintFP[MAXN];/// indicates the starting number of the edge corresponding to a position in the segment treeintSON[MAXN];/// son[u] means U's heavy sonintPosvoidInit () {tot=0; memset (head,-1,sizeof(head)); pos=0; memset (son,-1,sizeof(son));/// analog adjacency tablevoidAddedge (intUintV) {edge[tot].to=v; Edge[tot].next=head[u]; head[u]=tot++;}/// first time DFS find Fa,num,deep,son equivalentvoidDFS1 (intUintPreintd) {deep[u]=d; Fa[u]=pre; num[u]=1; for(inti=head[u];i!=-1; i=edge[i].next) {intv=edge[i].to;if(V!=pre) {DFS1 (v,u,d+1); NUM[U]+=NUM[V];/// determine the heavy son of U if(son[u]==-1|| Num[v]>num[son[u]]) son[u]=v; } }} ///second time DFS to find top and PvoidGetPosintUintSP) {top[u]=sp; p[u]=pos++; Fp[p[u]]=u;if(son[u]==-1)return;/// Guarantee continuous distribution of heavy-chain upper-edge in segment treeGetPos (SON[U],SP); for(inti=head[u];i!=-1; i=edge[i].next) {intv=edge[i].to;if(V!=son[u]&&v!=fa[u])/// Treatment of other nodes that are not heavy edgesGetPos (V,V); }}/// line Treestructnode{intL,r;intMax;} segtree[maxn*3];voidBuildintIintLintR) {segtree[i].l=l; Segtree[i].r=r; Segtree[i]. max=0;if(L==R)return;intMid= (L+R)/2; Build (i<<1, L,mid); Build ((i<<1)|1, mid+1, r);}voidPUSH_UP (inti) {segtree[i]. Max=max (segtree[i<<1]. max,segtree[(i<<1)|1]. MAX);}/// Single-point update K value is ValvoidUpdateintIintKintVal) {if(segtree[i].l==k&&segtree[i].r==k) {Segtree[i]. Max=val;return; }intMid= (SEGTREE[I].L+SEGTREE[I].R)/2;if(k<=mid) Update (i<<1, K,val);ElseUpdate ((i<<1)|1, K,val); PUSH_UP (i);} ///Interval query: Maximum value in [L,r]intQueryintIintLintR) {if(SEGTREE[I].L==L&&SEGTREE[I].R==R)returnSegtree[i]. Max;intMid= (SEGTREE[I].L+SEGTREE[I].R)/2;if(R<=mid)returnQuery (i<<1, l,r);Else if(L>mid)returnQuery ((i<<1)|1, l,r);Else returnMax (Query (i<<1, L,mid), query (i<<1)|1, mid+1, r));}/// Find the maximum value for the u->v edgeintFindintUintV) {intF1=top[u];intF2=TOP[V];inttmp=0; while(F1!=F2) {/// always guarantee DEEP[F1]>=DEEP[F2] if(Deep[f1]<deep[f2]) {swap (F1,F2); Swap (U,V); } Tmp=max (Tmp,query (1, P[f1],p[u])); U=FA[F1]; F1=top[u]; }if(U==V)returntmpif(Deep[u]>deep[v]) swap (U,V);returnMax (Tmp,query (1, P[son[u]],p[v]));}inte[maxn][3];intMain () {intTintN,u,v;//Freopen ("In.txt", "R", stdin);scanf"%d", &t); while(t--) {init (); scanf"%d", &n); for(intI=0; i<n-1; i++) {scanf ("%d%d%d", &e[i][0],&e[i][1],&e[i][2]);/// Note that two-way edges are addedAddedge (e[i][0],e[i][1]); Addedge (e[i][1],e[i][0]); } DFS1 (1,0,0); GetPos1,1); Build1,0, pos-1); ///Below is an operation to update the segment tree with each edge for(intI=0; i<n-1; i++) {if(deep[e[i][0]]>deep[e[i][1]]) Swap (e[i][0],e[i][1]); Update1, p[e[i][1]],e[i][2]); }Charop[Ten]; while(SCANF ('%s ', op)) {if(op[0]==' D ') Break; scanf"%d%d", &u,&v);if(op[0]==' Q ') printf ("%d\n", find (u,v));/// Enquiry ElseUpdate1, p[e[u-1][1]],V);// Modify} }return 0;}
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Tree chain split template + entry question Spoj-qtree