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...