反正就記一記自己學到了什麼而已,加深印象
好吧其實現在只會倍增lca,好像還有其他的演算法(看oi-wiki)但是暫時不想學
第一步
在樹上用dfs預處理出每乙個節點的father,用乙個二維陣列fa(i,j)表示節點i往上跳2j步的祖先,由常識我們就知道fa[i][j] = fa[fa[i][j - 1]][j - 1]
如果不懂
那就不怪我了
那就聽我講
fa[i][j]的意思在前面我已經告訴你了,那麼fa[i][j - 1]不就是節點i往上跳2j-1
步的祖先嗎,所以這個祖先再往上跳2j-1步不就是我們要的fa[i][j]了嗎
就是分成兩次跳嘛
是不是懂了好的我當你懂了
所以呢節點的father我們就都處理好了。那麼深度的處理就是一層一層往下加而已,至於怎麼dfs直接看**吧!
void dfs(intu)
for(int i = head[u];i;i =e[i].next)
}}
第二步我們要怎麼求兩個點x和y的lca呢?讓這兩個點同時往上跳直到他們相同不就完事了嗎
當然沒有這麼簡單啦 這樣子可能會跳過頭過程自行腦補
那我們就讓他們跳到lca的兒子那嘛,然後要利用倍增的思想步長從大到小去跳就行啦
最後lca就是fa[x][0]啦喜聞樂見**環節
int lca(int x,inty) }
return fa[x][0
];}
做一道模板題試一試水
這道題比較難
LCA離線演算法學習筆記
lca離線,採用的是遞迴的tarjan演算法,利用了樹深度優先遍歷的性質可以在一次遍歷過程中巧妙的求解出查詢的最接近公共祖先,時間複雜度是o n q 但前提是需要離線儲存所有詢問。演算法思路如下 當前dfs遍歷到節點u,先將vis u 標記成true,然後處理以u為根節點的子樹,子樹處理完成後,將這...
演算法 學習筆記
1.輸入輸出演算法至少有乙個或多個輸出 2.有窮性 3.確定性 4.可行性 1.正確性a.演算法程式沒有語法錯誤 b.演算法程式對於合法的輸入資料能夠產生滿足要求的輸出結果 c.演算法程式對於非法的輸入資料能夠得出滿足規格說明的結果 d.演算法對於精心選擇的,甚至刁難的測試資料都有滿足要求的輸出結果...
演算法學習筆記
複雜度分析 1.只關注迴圈次數最多的一行 2.總複雜度等於量級最大 的複雜度 3.巢狀 的複雜度等於巢狀 內外複雜度的乘積 單鏈表結構和順序儲存結構的優缺點 儲存分配方式 時間效能 空間效能 單鏈表結構 用一組任意的儲存單元存放線性表元素 查詢 o n 插入和刪除 找到某位置的指標後,插入和刪除的時...