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 } 洛谷p3379 如題,給定一棵有根多叉樹,請求出指定兩個點直接最近的公共祖先。輸入格式 第一行包含三個正整數n m s,分別表示樹的結點個數 詢問的個數和樹根結點的序號。接下來n 1行每行包含兩個正整數x y,表示x結點和y結點之間有一條直接連線的邊 資料保證可以構成樹 接下來m行每行包含兩個正整數... lca演算法樸素演算法 也就是我們所說的暴力演算法,大致的思路是從樹根開始,往下迭代,如果當前結點比兩個結點都小,那麼說明要從樹的右子樹中找 相反則從左子樹中查詢 直到找到乙個結點在當前結點的左邊,乙個在右邊,說明當前結點為最近公共祖先,如果乙個結點是另外乙個結點的祖先,那麼返回前面結點的父親結點即... 直接暴力搜尋參考 普通搜尋每次查詢都需要 樸素演算法是一層一層往上找,倍增的話直接預處理出乙個 具體做法是 維護乙個 的關係來線性求出這個陣列 int anc n 31 int dep n 記錄節點深度 void dfs int u,int parent for int i 0 i g u size...最近公共祖先(LCA) RMQ解決
最近公共祖先 python 最近公共祖先
最近公共祖先 LCA 最近公共祖先