三種LCA演算法(二) Tarjan演算法

2021-08-07 08:31:12 字數 1209 閱讀 6029

tarjan演算法也是一種常用的解決lca問題的演算法,演算法複雜度低,o(n + q),q為查詢次數,基於

dfs+並查集

,離線演算法

(首先讀入所有的詢問(求一次lca叫做一次詢問),然後在演算法執行過程中完成所有查詢,把查詢結果儲存起來,再去根據每次查詢直接輸出結果

),離線演算法侷限性較大。

演算法思路:

tarjan演算法也是基於dfs的,

其中關於集合的操作都是使用並查集高效完成,由於並查集的時間複雜度接近常數,所以演算法十分高效。

**:

#include #include #include #include using namespace std;

int n;//樹節點數量

//前向星存樹

int cnt1, head1[10005];

struct edges edge[20010];

//前向星存查詢

int cnt2, head2[10005];

struct query q[200010];

int answer[100005];//查詢結果(查詢下標->查詢結果)

int fa[10005],rank[10005];//並查集

int book[10005];//標記是否檢查過

int ancestor[10005];//祖先 此處fa和ancestor的區別是,fa實際上代表的是乙個集合,用於合併後的效果;而ancestor是為了實現演算法而指定的集合祖先

void addedge(int x, int y)

void addquery(int x, int y, int index)

int find(int x)

void merge(int x, int y) }}

void dfs(int x, int fa)

book[x] = 1;

for (int i = head2[x]; i; i = q[i].next) }}

void init()

memset(::rank, 0, sizeof(::rank));

}int main()

for (int i = 0; i < q; i++)

dfs(0,-1);//設0為根

for (int i = 0; i < q; i++)

} return 0;

}

LCA問題的三種求法

先來看一道例題 hdu 2586 how far away 題目描述的就是給你一棵n個節點的樹,然後q次詢問,每次詢問的內容是節點x和節點y的最近公共祖先 lca 接下來就來說一說lca 最近公共祖先 你需要準備的預備知識 st表處理rmq問題 並查集的思想以及實現 dfs遍歷整棵樹,維護一些值 求...

使用JS實現三種基本的排序演算法以及三種演算法的比較

function bubblesort arr if arr.length 0 arr.length 1 for let outer arr.length outer 2 outer return arr 選擇排序我們也需要用到巢狀迴圈,演算法思路如下 從陣列的第乙個元素開始,將第乙個元素逐個與其他...

FIFO LRU LFU三種演算法

提到快取,有兩點是必須要考慮的 1 快取資料和目標資料的一致性問題。2 快取的過期策略 機制 其中,快取的過期策略涉及淘汰演算法。常用的淘汰演算法有下面幾種 1 fifo firstin first out 先進先出 2 lru leastrecently used 最近最少使用 3 lfu lea...