LCA 離線tarjan演算法

2021-08-15 02:14:38 字數 2072 閱讀 3639

對於最近公共祖先問題,我們先來看這樣乙個性質,當兩個節點(u,v)的最近公共祖先是x時,那麼我們可以確定的說,當進行後序遍歷的時候,必然先訪問完x的所有子樹,然後才會返回到x所在的節點。這個性質就是我們使用tarjan演算法解決最近公共祖先問題的核心思想。

同時我們會想這個怎麼能夠保證是最近的公共祖先呢?我們這樣看,因為我們是逐漸向上回溯的,所以我們每次訪問完某個節點x的一棵子樹,我們就將該子樹所有節點放進該節點x所在的集合,並且我們設定這個集合所有元素的祖先是該節點x。那麼我們有理由相信, 任何乙個不屬於已經訪問的節點和已經訪問的節點的lca一定是當前這個根節點. 於是我們每次訪問完一棵子樹, 只需要將子樹放進根節點對應的集合即可.

poj 1470 :給出一棵樹,給出若干個u,v,然後求出u,v的lca,輸出每個點座位lca的次數,

#include#include#include#includeusing namespace std;

const int maxn = 100000 + 10;

typedef long long ll;

#define clr(x,y) memset(x,y,sizeof x)

#define inf 0x3f3f3f3f

const ll mod = 1e9 + 7;

typedef pairp;

vectorg[maxn],q[maxn];

int ans[maxn],fa[maxn],in[maxn];

bool vis[maxn];

int finds(int x)

void dfs(int u)

vis[u] = true;

for(int i = 0;i < q[u].size();i ++)

}}int main()

}int m;scanf("%d",&m);

while(m --)

for(int i = 1;i <= n;i ++)if(!in[i])

dfs(root);

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

if(ans[i])printf("%d:%d\n",i,ans[i]);

}return 0;

}

hdu 4547 

思路:求出lca,進行操作。應為都為查詢,所以可以離線。

#include#include#include#include#include#includeusing namespace std;

const int maxn = 1e5 + 10;

typedef long long ll;

#define clr(x,y) memset(x,y,sizeof x)

#define inf 0x3f3f3f3f

const ll mod = 1e9 + 7;

typedef pairp;

mapms;

vectorg[maxn];

struct node

;int ans[maxn],lca[maxn];

vectorq[maxn];

int in[maxn],fa[maxn],dep[maxn];

bool vis[maxn];

int finds(int x)

void dfs(int u,int d)

vis[u] = true;

for(int i = 0;i < q[u].size();i ++)

}}int u[maxn],v[maxn];

int main()

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

);q[ms[b]].push_back((node));

u[i] = ms[a];v[i] = ms[b];

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

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

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

cout << ans[i] << endl;

}return 0;

}

LCA離線演算法tarjan

lca演算法 lca least common ancestor 是指在一棵樹中,距離兩個點最近的兩者的公共節點。也就是說,在兩個點通往根的道路上,肯定會有公共的節點,我們就是要求找到公共的節點中,深度盡量深的點。還可以表示成另一種說法,就是如果把樹看成是乙個圖,這找到這兩個點中的最短距離。本文先介...

LCA的離線演算法Tarjan

總的來說是深度遍歷。以根為節點建立並查集。比如說求p,v的lca。當訪問到p的時候檢查v是否已經訪問過。如果訪問過,那麼他們的lca就是v現在所在的並查集裡面的元素。如果沒有訪問到。那麼等到v訪問到的時候可以操作一下。充分利用了遞迴這個操作,所以不必要儲存以前的東西,自然而然的就將u裡面的所有的子節...

關於LCA的離線演算法 Tarjan

利用並查集優越的時空複雜度,我們可以實現lca問題的o n q 演算法,這裡q表示詢問 的次數。tarjan演算法基於深度優先搜尋的框架,對於新搜尋到的乙個結點,首先建立由這個結點 構成的集合,再對當前結點的每乙個子樹進行搜尋,每搜尋完一棵子樹,則可確定子樹 內的lca詢問都已解決。其他的lca詢問...