NOIP模板複習 2 LCA的三種解法

2022-08-17 19:12:20 字數 2147 閱讀 9860

lca還是圖論中蠻重要的部分,解法眾多,這裡只拿三個比較常用的板子出來說說

1.樹上倍增

1.1演算法原理

1.2演算法實現

2.tarjan演算法

2.1演算法原理

2.2演算法實現

3.rmq實現

3.1演算法原理

3.2演算法實現

4.總解

倍增演算法主要是利用\(2^i\)可以相加組成任何數這一性質來組織資訊轉移狀態,具體就是維護乙個倍增陣列\(f[i][j]\)表示編號為\(i\)的節點向上跳\(2^j\)步所到達的點。通過簡單的思考我們可以發現節點\(i\)向上跳\(2^j\)步的節點是\(i\)號節點向上跳\(2^\)步的節點再向上跳\(2^\)步所到達的節點,因此我們可以得到乙個式子:\(f[i][j]=f[f[i][j-1]][j-1]\),通過這個式子,我們可以輕易的在很短的時間內推出倍增陣列。

而有了倍增陣列就好辦了,我們可以利用dfs求出每個節點距根節點的深度,然後我們便可以先將兩個節點上跳到同一高度(注:以後上跳都可以利用倍增陣列完成),再將兩個節點同時上跳。當兩個節點的祖先都相同時,便找到了兩個節點的最近公共祖先。

該演算法單個查詢的時間複雜度為\(o(log(n))\)。

**如下#include #include #include #include #include #include #include using namespace std;

vectortree[1005];

int deep[1005];

int anc[1005][25];

int father[1005];

void dfs(int root)//預處理出倍增陣列和深度

int len=tree[root].size();

for(int i=0;i=0;i--)//將兩個點調整到同一高度

}if(a==b)

for(int i=19;i>=0;i--)

}return anc[a][0];

}int main()

father[1]=1;

dfs(1);

for(int i=1;i<=t;i++)

memset(used,0,sizeof(used));

return ;

}int find(int x)

return father[x]=find(father[x]);

} void unions(int x, int y)

father[x]=y;

return ;

}void tarjan(int root)

]\)的區間的最值。而通過動態規劃我們便可以預處理出\(f\)陣列。首先\(f[i][0]\)的值就是它本身,而\(f[i][j]\)可以分為\((i,i+2^-1)\)和\((i+2^,i+2^j-1)\)兩段區間使得兩段區間長度都為\(2^\)。這樣便可以得到狀態轉移方程\(f[i][j]=max(f[i][j-1],f[i+2^][j-1])\)。

而rmq的查詢可以通過乙個中間值\(k=log_(j-i+1)\),則區間\((i,j)\)的最值就為\(max(f[i][k],f[j-2^k+1][k])\)。這樣便可以在\(o(1)\)的時間內查詢區間的最值了。

**如下#include #include #include #include #include #include #include using namespace std;

vectortree[1005];

int cnt=1;

int st[1005<<1][20];

int deep[1005<<1];

int id[1005];

int idx[1005<<1];

void getst(int n)//預處理出st表

for(int j=1;(1return idx[ask(l,r)];

}int main()

dfs(1,-1,0);

getst(2*n);

for(int i=1;i<=t;i++)

{scanf("%d %d",&a,&b);

cout《而tarjan演算法是三種演算法中效率最高的,但因其是離線演算法所以應用範圍不是很廣,在面對大量的詢問是還是乙個不錯的演算法,且其實現簡單,不容易出錯。

在考場上的推薦度為rmq\(\leq\)tarjan\(\leq\)倍增。

LCA問題的三種求法

先來看一道例題 hdu 2586 how far away 題目描述的就是給你一棵n個節點的樹,然後q次詢問,每次詢問的內容是節點x和節點y的最近公共祖先 lca 接下來就來說一說lca 最近公共祖先 你需要準備的預備知識 st表處理rmq問題 並查集的思想以及實現 dfs遍歷整棵樹,維護一些值 求...

C 類模板的三種特化

說起c 的模板及模板特化,相信很多人都很熟悉 但是說到模板特化的幾種型別,相信了解的人就不是很多。我這裡歸納了針對乙個模板引數的類模板特化的幾種型別,一是特化為絕對型別 二是特化為引用,指標型別 三是特化為另外乙個類模板。這裡用乙個簡單的例子來說明這三種情況 general version temp...

C 類模板的三種特化

說起c 的模板及模板特化,相信很多人都很熟悉 但是說到模板特化的幾種型別,相信了解的人就不是很多。我這裡歸納了針對乙個模板引數的類模板特化的幾種型別,一是特化為絕對型別 二是特化為引用,指標型別 三是特化為另外乙個類模板。這裡用乙個簡單的例子來說明這三種情況 general version temp...