1. 程式人生 > >LCA在線算法詳解

LCA在線算法詳解

htm i++ class 屬於 介紹 輸入輸出 http arch nbsp

LCA(最近公共祖先)的求法有多種,這裏先介紹第一種:在線算法。

聲明一下:下面的內容參考了http://www.cnblogs.com/scau20110726/archive/2013/05/26/3100812.html。

在線算法就是利用了DFS和RMQ兩種算法,它先是預處理好所有情況,然後根據輸入輸出答案,在輸入比較多的時候用比較好。

技術分享

技術分享

上面兩張圖介紹了在線算法的做法,要理解並不難,下面附上實現代碼:

 1 /*******************************
 2 dfs實現代碼
 3 *******************************/
 4 
 5 void
dfs(int u, int dep) 6 { 7 vis[u]=1; 8 ver[++tot]=u; //遍歷序列 9 first[u]=tot; //結點第一次出現位置 10 deep[tot]=dep; //深度 11 for(int i=head[u];i!=-1;i=e[i].next) 12 { 13 if(!vis[e[i].v]) 14 { 15 int v=e[i].v, w=e[i].w; 16 dfs(v,dep+1
); 17 ver[++tot]=u; //回溯 18 deep[tot]=dep; 19 } 20 } 21 }

接下來是ST算法,也就是RMQ,計算出所有的d[i][j]。

 1 void ST(int n)
 2 {
 3     for(int i=1;i<=n;i++)  dp[i][0]=i;
 4     for(int j=1;(1<<j)<=n;j++)
 5         for(int i=1;i+(1<<j)-1<=n;i++)
6 { 7 int a=dp[i][j-1],b=dp[i+(1<<(j-1))][j-1]; 8 dp[i][j]=deep[a]<deep[b]?a:b; 9 } 10 }

最後是LCA的查詢部分,其實也屬於RMQ。

1 int LCA(int u, int v)
2 {
3     int x=first[u], y=first[v];   //查找出他最先出現的地方
4     if(x>y)  swap(x,y);
5     int res=RMQ(x,y);    //查詢出的是他祖先的下標
6     return ver[res];   
7 }

LCA在線算法詳解