利用dfs和並查集實現點對的最近公共祖先,首先遞迴到葉子節點,然後在返回時才確定父子關係,按照這樣的順序確定父子關係之後,最早出現的公共父節點便是最近公共祖先。
#include
using
namespace
std;
const
int maxn=1000;
const
int maxm=1000;
int lca[maxn+5][maxn+5];
vector
nxt[maxn+5];
vector
q[maxn+5];
int qx[maxm+5],qy[maxm+5];//儲存要查詢的點對
int p[maxn+5];//並查集
int find(int x)
void dfs(int cur,int fa)
for(int i=0;i//確定公共祖先,相同的點對會兩次到達這裡
int x=q[cur][i];
lca[min(cur,x)][max(cur,x)]=find(x);
//第一次的時候cur被訪問,x未訪問,這時find(x)的值是無效的,這一遍的有無都無所謂
//第二次的時候cur和x都被訪問且x是在cur之前訪問過的,這時候x的最上面的祖先就是最近公共祖先
cout
}}int main()
for(int i=1;i<=m;i++)
memset(p,-1,sizeof(p));//並查集初始化
dfs(1,-1);
for(int i=1;i<=m;i++)
}
最近公共祖先 LCA 最近公共祖先
直接暴力搜尋參考 普通搜尋每次查詢都需要 樸素演算法是一層一層往上找,倍增的話直接預處理出乙個 具體做法是 維護乙個 的關係來線性求出這個陣列 int anc n 31 int dep n 記錄節點深度 void dfs int u,int parent for int i 0 i g u size...
最近公共祖先 最近公共祖先(LCA)
如題,給定一棵有根多叉樹,請求出指定兩個點直接最近的公共祖先。輸入格式 第一行包含三個正整數n m s,分別表示樹的結點個數 詢問的個數和樹根結點的序號。接下來n 1行每行包含兩個正整數x y,表示x結點和y結點之間有一條直接連線的邊 資料保證可以構成樹 接下來m行每行包含兩個正整數a b,表示詢問...
Tarjan離線演算法 (LCA最近公共祖先)
tarjan離線演算法是利用並查集和dfs來達到離線處理的目的 我們都知道,對於一棵樹,後序遍歷一遍,訪問它的根的時機一定是後與它的孩子的。換一句話,當開始遍歷它的根節點的時候,它遍歷過的孩子的公共祖先一定是這個根而這也就成為了我們解題的思想。由於是需要對整樹進行dfs,所以tarjan需要在所有資...