Http://poj.org/problem? Id = 1330
This is the offline version of tarjian:
For all the children of a father. We all go to recursive LCA. If the current vertex is one of the two vertices to be queried and the other has been accessed. Output.
Method 1: Tarjan offlineAlgorithm
When learning offline algorithms, you must first consolidate deep search and query the set.
The Tarjan offline algorithm is based on deep priority search. We start from the root and search for a node. When we find a node, we first determine whether all the subnodes of the node have accessed it. If all the subnodes have accessed it, then, it determines whether the node asks one of the points. If yes, it determines whether the point corresponding to the node has been accessed. If yes, then their recent common ancestor is the current node of the node that has been accessed. If another node is not accessed, the in-depth search will continue.
1 # Include <iostream> 2 # Include < String . H> 3 # Include <algorithm> 4 # Include <stdio. h> 5 # Define Maxn 12000 6 # Include <vector> 7 Using Namespace STD; 8 Int Father [maxn]; 9 Int Visit [maxn]; 10 Int Root [maxn]; 11 Vector <Int > Node [maxn]; 12 Int St, en; 13 Int N; 14 Void Init () 15 { 16 Cin> N; 17 For (Int I = 1 ; I <= N; I ++ ) 18 { 19 Father [I] = I; 20 Root [I] = 1 ; 21 Visit [I] = 0 ; 22 Node [I]. Clear (); 23 } 24 For ( Int I = 1 ; I <n; I ++ ) 25 { 26 Int A, B; 27 Cin> A> B; 28 Node [A]. push_back (B ); 29 Root [B] = 0 ; 30 } 31 Cin> st> En; 32 } 33 34 Int Find ( Int A) 35 { 36 If (Father [a]! = A) 37 { 38 Father [a] = Find (father [a]); 39 } 40 Return Father [a]; 41 } 42 Void Union ( Int A,Int B) 43 { 44 Int Fa = Find (); 45 Int Fb = Find (B ); 46 If (Fa! = FB) 47 Father [FB] = Fa; 48 } 49 50 Void LCA ( Int Parent) 51 { 52 For ( Int I = 0 ; I <node [Parent]. Size (); I ++ ) 53 { 54 LCA (node [Parent] [I]); 55 Union (parent, node [Parent] [I]); 56 } 57 Visit [Parent] = 1 ; 58 If (Parent = sT && Visit [En]) 59 { 60 Cout <find (en) < Endl; 61 Return ; 62 } 63 Else 64 If (Parent = en && Visit [st]) 65 { 66 Cout <find (ST) < Endl; 67 Return ; 68 } 69 } 70 71 Int Main () 72 { 73 Int Test; 74 Cin> Test; 75 For ( Int I = 1 ; I <= test; I ++ ) 76 { 77 Init (); 78 79 For ( Int I = 1 ; I <= N; I ++ ) 80 If (Root [I]) 81 { 82 83 LCA (I ); 84 Break ; 85 } 86 } 87 // System ("pause "); 88 Return 0 ; 89 }
This is an online version.
# Include <iostream> # Include < String . H> # Include <Stdio. h> # Include <Algorithm> # Include <Vector> # Include <Math. h> # Define Maxn 10005 Using Namespace STD; vector < Int > Node [maxn]; Int Indegree [maxn]; Int E [maxn * 2 + 2 ]; Int R [maxn]; Int D [maxn * 2 + 2 ]; Int DP [maxn * 2 + 2 ] [ 100 ]; Int N; Int St; Int En; Int P; Void Init () {CIN >N; For ( Int I = 1 ; I <= N; I ++ ) {Node [I]. Clear (); indegree [I] = 0 ;} For ( Int I = 1 ; I <n; I ++ ){ Int A, B; CIN > A>B; node [A]. push_back (B); indegree [B] ++ ;} P = 0 ; CIN >>> St> En ;} Void DFS ( Int Root, Int Deep) {P ++ ; E [p] = Root; d [p] = Deep; R [root] = P; For ( Int I = 0 ; I <node [root]. Size (); I ++ ) {DFS (node [root] [I], deep + 1 ); P ++ ; E [p] = Root; d [p] = Deep ;}} Int Min ( Int A, Int B ){ Return D [a] <D [B]? A: B ;} Void Rmq ( Int A [], Int Num) {memset (DP, 0 , Sizeof (DP )); For ( Int I = 1 ; I <num; I ++ ) DP [I] [ 0 ] =I; Int K = Log (( Double ) (Num- 1 )/Log ( 2.0 ); For ( Int J = 1 ; J <= K; j ++ ) For ( Int I = 1 ; I + ( 1 <J )-1 <Num; I ++ ) {DP [I] [J] = D [DP [I] [J- 1 ] <D [DP [I + ( 1 <(J- 1 )] [J- 1 ]? DP [I] [J- 1 ]: DP [I + ( 1 <(J- 1 )] [J- 1 ] ;}} Int LCA ( Int A [],Int St, Int En ){ Int K = Log ( Double (En-ST + 1 )/Log ( 2.0 ); Return D [DP [st] [k] <D [DP [en -( 1 <K) + 1 ] [K]? DP [st] [k]: DP [en -( 1 <K) + 1 ] [K];} Int Main (){ Int Test; CIN > Test; For ( Int I = 1 ; I <= test; I ++ ) {Init (); Int Root; For ( Int I = 1 ; I <= N; I ++) If (! Indegree [I]) {Root = I; Break ;} DFS (root, 0 ); Rmq (D, 2 * N ); If (R [st] < R [En]) cout <E [LCA (D, R [st], R [En])] < Endl; Else Cout <E [LCA (D, R [En], R [st])] < Endl;} system ( " Pause " ); Return 0 ;}