1 #include <iostream> 2 #include <vector> 3 #include <algorithm> 4 #define MAXN 100 5 //2^MAXLOG2>=最大深度 6 #define MAXLOG2 7 7 using namespace std; 8 9 vector<int>G[MAXN]; 10 int depth[MAXN]; 11 int ancestor[MAXN][MAXLOG2]; 12 13 void creat()//輸入並存儲樹 14 { 15 int n,x,y; 16 cin>>n;//n條邊 17 for(int i=0;i<n;i++) 18 { 19 cin>>x>>y; 20 G[x].push_back(y); 21 G[y].push_back(x); 22 } 23 } 24 void dfs(int x,int father) 25 { 26 depth[x]=depth[father]+1;//計算x深度 27 ancestor[x][0]=father; 28 //計算x結點的2^i步祖先 29 for(int i=1;i<MAXLOG2;i++) 30 //由於是dfs,因此深度小的結點的ancestor總會先算出來 31 //MAXLOG2太大了會怎樣?由於ancestor[0][i]=0,因此無論怎樣往上走都是0 32 ancestor[x][i]=ancestor[ancestor[x][i-1]][i-1]; 33 for(int i=0;i<G[x].size();i++) 34 if(G[x][i]!=father)dfs(G[x][i],x); 35 } 36 int lca(int x,int y) 37 { 38 if(depth[x]<depth[y])swap(x,y); 39 /*假設x與y深度相差z,x每次走2^i(i從最大每次循環減小1)步總能到達y的深度 40 證實:將z轉換成二進制,再轉換成十進制 41 則確定等於2^i1 + 2^i2 + 2^i3 ... 形式 */ 42 for(int i=MAXLOG2-1;i>=0;i--) 43 //如何防止走多了?走完後的深度比y還小,說明走多了,這時候咱們就不走 44 if(depth[ancestor[x][i]]>=depth[y])x=ancestor[x][i]; 45 if(x==y)return x; 46 //假設x與LCA相距L步,那麼x,y都走L-1步仍然不相等,下面的循環是讓x,y走L-1步 47 for(int i=MAXLOG2-1;i>=0;i--) 48 /*如何防止走多了? 49 注意循環結束條件,並不是當x,y走完後相等 50 若是以x,y相等爲結束條件,則有可能會走過了 51 此循環的目的是爲了讓x,y走L-1步 52 LCA至關於x,y的中點 53 爲何必定恰好走L-1步? 54 首先能肯定的是存在兩個結點再往上一步就是LCA 55 此循環讓x,y只要不相等就往上走,x,y確定會到達這兩個結點 56 即x,y走L-1步會到達那兩個結點。本身能夠畫圖試試*/ 57 if(ancestor[x][i]!=ancestor[y][i]) 58 { 59 x=ancestor[x][i]; 60 y=ancestor[y][i]; 61 } 62 return ancestor[x][0]; //即x再向上走1(2^0)步便是LCA 63 } 64 int main() 65 { 66 creat();//數據要輸入 67 dfs(1,0); 68 //cout<<lca(7,6); 69 return 0; 70 }