Topic
View original title-HDU6031 innumerable ancestors
Title Description
There is a root tree with n nodes, the root node is 1, its depth is 1, and now there are M queries, each asking for two sets a and B, asking what the depth of the LCA (x, y) (x∈a,y∈b) is.
Enter a description
There are multiple sets of data (number of data groups <=5)
For each set of data, the first 2 number n,m, which indicates the number of nodes and the number of queries that have a root tree. Then n-1 line, 2 number per line, a, B, indicates that there is a direct connecting edge between Node A and node A, and the next 2m line, each two lines, describes the collection A and set B of the current query, respectively, for a collection, in one row, the first number of K represents the number of elements in the collection, followed by the number of K
Output Description
An integer that represents the maximum depth of the LCA (x, y) (x∈a,y∈b).
Data Range
n,m<=100000, 1<=a,b<=n,σk<=100000, 1<= elements in the collection <=n
Solving
Ask for the maximum depth, then we think about whether we can answer the two points.
Of course, the conditions of the subject meet the premise of the two-point answer, the basic nature of the LCA is still more obvious. (assuming A and b depth as) set Anst[x][y] for node x to go up the Y-step to reach the ancestors, for a k, if ANST[A][K]==ANST[B][K], then for K ' (K ' >k), there must be anst[a][k ']==anst[b][k ' ]; for a k, if ANST[A][K]!=ANST[B][K], then for K ' (K ' <k), there must be Anst[a][k ']!=anst[b][k '), and LCA (A, B) =lca (Anst[a][k],anst[b] [K]).
Two points after the depth d is complete, then there is a sub-program to determine the matter.
So what if we decide?
Known ancestor depth, then you know the ancestors of each point, right? Then, judging whether there is a public ancestor, is actually to judge a set of the corresponding ancestor set and B set of the corresponding ancestor set whether there is the intersection-because σk<=100000, so for each set element to find its depth of the ancestors of this complexity seems to be insufficient, σk* N should be super (if someone uses Σk*n's judgment to get through the subject, kneeling for the code). So we have to find this ancestor faster, so what is it? Multiply Ah!
FA[I][J] Represents the ancestor of I with the depth difference of node I 2^j, it is not difficult to write the transfer equation:
Fa[i][0]=father[i],fa[i][j]=fa[fa[i][j-1]][j-1] (Father[i] represents the Father node of node i)
So, the ancestor of a certain depth is similar to the first half of the multiplication of the LCA .
As for the two sets of the judgment intersection, is the order, and then two hands sweep past it can be.
Note: In the case of ancestors, we must first filter out the illegal ancestors, in judging the intersection, pay attention to the boundary situation!
Code
#include <cstring>#include<cstdlib>#include<algorithm>#include<cstdio>#include<cmath>using namespacestd;Const intn=100005, m=n*2, rt=1;structedge{intCnt,y[m],nxt[m],fst[n]; void Set() {CNT=0; memset (Y,0,sizeofy); memset (NXT,0,sizeofNXT); memset (FST,0,sizeofFST); } voidAddintAintb) {y[++cnt]=b,nxt[cnt]=fst[a],fst[a]=CNT; }}e;intn,m,depth[n],fa[n][ -],ta,a[n],tb,b[n],ansta[n],anstb[n];voidBuildintPrevintRT) {fa[rt][0]=prev,depth[rt]=depth[prev]+1; for(intI=1;(1<<i) <=depth[rt];i++) Fa[rt][i]=fa[fa[rt][i-1]][i-1]; for(intI=e.fst[rt];i;i=E.nxt[i])if(e.y[i]!=prev) build (Rt,e.y[i]);}intGet_kth_anst (intPintk) { for(inti=k,j=0;i>0; i>>=1, J + +) if(i&1) P=Fa[p][j]; returnp;}BOOLCheckintd) { intat=0, bt=0; for(intI=1; i<=ta;i++) if(depth[a[i]]>=d) ansta[++at]=get_kth_anst (a[i],depth[a[i]]-d); for(intI=1; i<=tb;i++) if(depth[b[i]]>=d) anstb[++bt]=get_kth_anst (b[i],depth[b[i]]-d); if(at==0|| bt==0) return 0; intPa=1. P =1; Sort (Ansta+1, ansta+at+1); Sort (Anstb+1, anstb+bt+1); if(ansta[1]==anstb[1]) return 1; while(pa<=at&&pb<=BT) { while(pa<=at&&ansta[pa]<ANSTB[PB]) PA++; if(pa>At ) Break; if(ansta[pa]==ANSTB[PB])return 1; while(pb<=bt&&ansta[pa]>ANSTB[PB]) PB++; if(pb>BT) Break; if(ansta[pa]==ANSTB[PB])return 1; } return 0;}intMain () { while(~SCANF ("%d%d",&n,&m)) {e.Set(); for(intI=1, a,b;i<n;i++) scanf ("%d%d",&a,&b), E.add (A, B), E.add (B,a); depth[0]=-1; Build (0, RT); while(m--) {scanf ("%d",&ta); for(intI=1; i<=ta;i++) scanf ("%d",&A[i]); scanf ("%d",&TB); for(intI=1; i<=tb;i++) scanf ("%d",&B[i]); intle=0, ri=n-1, mid,ans=0; while(le<=RI) {Mid= (Le+ri) >>1; if(check (mid)) Le=mid+1, ans=mid; ElseRI=mid-1; } printf ("%d\n", ans+1); } } return 0;}
In order to facilitate people to pick up, specially attached a data-making Pascal code, used to pat.
varT, I:longint;functionmin (A, b:longint): Longint; begin if(A > B) Thenexit (b); Exit (a); End;proceduremake_list (n, M:longint); varI, J:longint; beginwrite (M,' '); J:=0; forI: =1 toM Do beginJ:= j + Random (N-j-M + i) +1; Write (J,' '); End; Writeln; End;procedureMkdata; ConstMAXN= Max; MAXM= Max; Add= +; varN, M, I, J, X, Y, A, b:longint; beginN:= Random (MAXN) +1; M:= Random (MAXM) +1; Writeln (N,' ', M); forI: =2 toN Do beginx:=i; Y:= Random (I-1) +1; if(Random (2) =1) Thenwriteln (x,' ', y)Elsewriteln (Y,' ', x); End; Writeln; forI: =1 toM Do beginA:= Min (Random (MAXNDivM + Add) +2, N); B:= Min (Random (MAXNDivM + Add) +2, N); Make_list (n, a); Make_list (n, b); End; Writeln; End;beginassign (output,'anst.in'); Rewrite (output); Randomize T:= Random (2) +1; forI: =1 toT DoMkdata; Close (output);End.
HDU6031 Innumerable Ancestors Multiplier-test instructions Detailed summary-algorithmic explanation