最近公共祖先LCA RMQ轉化

2021-08-30 12:11:40 字數 1205 閱讀 1900

1,最近公共祖先(lca):

對於有根樹t的兩個結點u、v,最近公共祖先lca(t,u,v)表示乙個結點x,滿足x是u、v的祖先且x的深度盡可能大。

2,lca問題向rmq問題的轉化方法:(rmq返回最值的下標)

對樹進行深度優先遍歷,每當「進入」或回溯到某個結點時,將這個結點的深度存入陣列dfsnum最後一位。同時記錄結點i在陣列中第一次出現的位置(事實上就是進入結點i時記錄的位置),記做first[i]。如果結點dfsnum[i]的深度記做depth[i],易見,這時求lca(u,v),就等價於求 e[rmq(depth,first[u],first[v])],(first[u]

#include

#include

#include

using namespace std;

const int maxn=20010;

struct node //可以新增額外的資訊

;//注意vector在樹問題中的使用

vectortree[maxn];

int dfsnum[maxn]; //記錄遍歷的節點

int depth[maxn]; //記錄節點對應的深度

int first[maxn]; //記錄結點第一次訪問到時的下標

int top; //記錄總的步伐數

void dfs(int m,int f,int dep) //當前節點編號,父節點編號,深度

}int dp[maxn][18];

void makermqindex(int n,int b) //返回最小值對應的下標

int rmqindex(int s,int v,int b)

int lca(int x,int y)

int main()

;int y=;

node temp;

for(int i=0;idfs(1,-1,0); //根節點為1

cout<<"總數:"

cout<<"dfsnum:";

for(int i=0;icout

for(int i=0;icout

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

cout

}

最近公共祖先(LCA) RMQ解決

洛谷p3379 如題,給定一棵有根多叉樹,請求出指定兩個點直接最近的公共祖先。輸入格式 第一行包含三個正整數n m s,分別表示樹的結點個數 詢問的個數和樹根結點的序號。接下來n 1行每行包含兩個正整數x y,表示x結點和y結點之間有一條直接連線的邊 資料保證可以構成樹 接下來m行每行包含兩個正整數...

最近公共祖先 python 最近公共祖先

lca演算法樸素演算法 也就是我們所說的暴力演算法,大致的思路是從樹根開始,往下迭代,如果當前結點比兩個結點都小,那麼說明要從樹的右子樹中找 相反則從左子樹中查詢 直到找到乙個結點在當前結點的左邊,乙個在右邊,說明當前結點為最近公共祖先,如果乙個結點是另外乙個結點的祖先,那麼返回前面結點的父親結點即...

最近公共祖先 LCA 最近公共祖先

直接暴力搜尋參考 普通搜尋每次查詢都需要 樸素演算法是一層一層往上找,倍增的話直接預處理出乙個 具體做法是 維護乙個 的關係來線性求出這個陣列 int anc n 31 int dep n 記錄節點深度 void dfs int u,int parent for int i 0 i g u size...