lca(最近公共祖先),指對於一棵樹上任意兩個節點往上走最早都能到達的節點。
求lca有兩種方法,一種是倍增,另一種則是tarjan。。。。。。。。
tarjan巧妙利用並查集的思想;
這裡的tarjan是離線演算法
先tarjan下去;
首先有fa[num]=num;
回溯時將子節點的fa變為num
如果對於num的詢問中另乙個點已經訪問;
那他們的lca為另乙個點的find(fa)
原因:&&乙個點與另乙個點都位於以他們的lca為根節點的子樹中;
如果沒有相關點的資訊,只說明在該節點的上方,故回溯時把fa的變為父節點;
這裡的find是並查集中的代表元素。。。。。
再處理各種詢問
另外,兩點距離為dis[x]+dis[y]-2*dis[lca(x,y)];
附上原題**及位址
#include#include#include#define n 50001
using namespace std;
struct dataask[75001*2];
struct nodeedge[n*2+1];
int tot,tot1,n,m;
bool vis[n];
int dis[n],fa[n];
int head[n],head1[75001*2];
int find(int x)
void add1(int x,int y)
void dfs(int num,int hehe)
}void tarjan_lca_haha(int t)
for(int i=head1[t];i;i=ask[i].nxt)
if(vis[ask[i].to])
ask[i].ans=dis[ask[i].to]+dis[t]-2*dis[find(ask[i].to)];
}int main(){
scanf("%d",&n);
for(int i=1;i
關於LCA的離線演算法 Tarjan
利用並查集優越的時空複雜度,我們可以實現lca問題的o n q 演算法,這裡q表示詢問 的次數。tarjan演算法基於深度優先搜尋的框架,對於新搜尋到的乙個結點,首先建立由這個結點 構成的集合,再對當前結點的每乙個子樹進行搜尋,每搜尋完一棵子樹,則可確定子樹 內的lca詢問都已解決。其他的lca詢問...
LCA離線演算法tarjan
lca演算法 lca least common ancestor 是指在一棵樹中,距離兩個點最近的兩者的公共節點。也就是說,在兩個點通往根的道路上,肯定會有公共的節點,我們就是要求找到公共的節點中,深度盡量深的點。還可以表示成另一種說法,就是如果把樹看成是乙個圖,這找到這兩個點中的最短距離。本文先介...
LCA 離線tarjan演算法
對於最近公共祖先問題,我們先來看這樣乙個性質,當兩個節點 u,v 的最近公共祖先是x時,那麼我們可以確定的說,當進行後序遍歷的時候,必然先訪問完x的所有子樹,然後才會返回到x所在的節點。這個性質就是我們使用tarjan演算法解決最近公共祖先問題的核心思想。同時我們會想這個怎麼能夠保證是最近的公共祖先...