LCA求最近公共祖先

2021-09-26 06:10:19 字數 1692 閱讀 9009

parent[i][j]:表示節點u的第2^j個祖先

dis[i]:dfs時間戳,即節點到根節點距離,即深度

const int pow = 18; 

const int maxn=5e5+10;

int parent[maxn][pow+10];//parent[i][j]表示節點u的第2^j個祖先

vectoredge[maxn];

int dis[maxn];//dfs時間戳,即節點到根節點距離,即深度

void dfs(int u,int fa)

return a;

}

theme:求三個人位於不同的三個節點,求它們集合與一點共需花費的最少步數與點的編號。1<=n,m<=5*10^5

solution:設a,b,c兩兩的最近公共祖先分別為ab,ac,bc,三個點的最近公共祖先為與其它兩個不同的。則我們求出ab,ac,bc後判斷它們的相等關係即可,而所需距離由dis相減即可。

//三個點的最近公共祖先

#includeusing namespace std;

const int maxn=5e5+10;

const int pow = 18;

int parent[maxn][pow+10];//parent[i][j]表示節點u的第2^j個祖先

vectoredge[maxn];

int dis[maxn];

void dfs(int u,int fa)

return a;

}int main()

dfs(1,0);

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

else if(ab==ac)

else if(bc==ac)

}}

theme:給定一棵樹,n個節點,m此詢問,每次詢問與節點u為p級兄弟的個數,p級兄弟即a,b有公共的p級祖先。(1 ≤ n,m ≤ 10^5)

solution:首先通過lca演算法算出parent[i][j],在深蒐時記錄下進入每個節點的時間戳與離開該節點的時間戳,將每個深度的節點的時間戳用乙個vector記錄。則每次詢問時,先通過parent找到u的p祖先pa,再通過lower_bound()二分找出大於pa進入時間戳的個數與離開時間戳的個數,相減即可。

//找u的p級兄弟

#includeusing namespace std;

const int maxn=1e5+10;

const int pow = 18;

int parent[maxn][pow+10];//parent[i][j]表示節點u的第2^j個祖先

vectoredge[maxn];

vectordeep[maxn];

int dis[maxn];

int in[maxn],out[maxn];

int cnt,maxdept=0;

void dfs(int u,int fa)

return now;

}int main()

dfs(0,0);

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

sort(deep[i].begin(),deep[i].end());

cin>>m;

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

}}

求LCA(最近公共祖先)

演算法1 樹上倍增 hdu 2586 include include include define maxn 40000 5 define inf 999999999 using namespace std int n,m,t,q,head maxn x,y,z,vis maxn fa maxn c...

LCA 求最近公共祖先

洛谷3379 基本思路 要求兩個點的最近公共祖先,首先我們用乙個陣列fa x i 來表示節點x的向上2 i層的祖先編號,先dfs求出每個點的深度和預處理fa陣列。再求兩個節點的最近公共祖先時,先讓深度大的跳到相同的一層,再嘗試以log2 depth x 的跨度跳至祖先節點,相同時不跳 因為可能不是最...

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

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