補了一發lca,表示這東西表面上好像簡單,但是細節真挺多。
我學的是樹上倍增,倍增思想很有趣~~(爸爸的爸爸叫奶奶.偶不,爺爺)有乙個跟st表非常類似的東西,f[i][j]
表示j的第2^i的祖先,就是說f[0][x]是父親,f[1][x]是爺爺,f[2][x]是高祖父(爺爺的爺爺),f[3][x]是遠祖父(高祖父的高祖父)
搞個事:
扯回來,這個就是倍增的思想,可以方便的實現o(logn)的lca,現在讓你在構圖的時候搞好f陣列,一點問題都沒有了吧~按古制輩份分為:自己,
父親、祖父、曾祖、高祖、天祖、烈祖、太祖、遠祖、鼻祖。
然後怎麼求lca?首先,我們先讓深度比較深的點往上跳,然後兩個一起跳,直到跳到父親相同。那我們跳的時候,就像二進位制一樣,可以一次跳2^i次方
caioj1236:(赤裸裸的lca)
#include#include#include
#include
using
namespace
std;
struct
node
a[210000];int len,last[110000
];void ins(int x,int
y)//
f[i][j]表示j的第2^i的祖先
int bin[30],dep[110000],f[25][110000
];void dfs(int x,int fa)//
構樹 }
}int lca(int x,int
y)
return f[0
][x];
}int
main()
dep[
1]=1;dfs(1,0
);
while(m--)
return0;
}
演算法 樹上倍增求LCA
lca指的是最近公共祖先 least common ancestors 如下圖所示 4和5的lca就是2 那怎麼求呢?最粗暴的方法就是先dfs一次,處理出每個點的深度 然後把深度更深的那乙個點 4 乙個點地乙個點地往上跳,直到到某個點 3 和另外那個點 5 的深度一樣 然後兩個點一起乙個點地乙個點地...
樹上倍增法求LCA
我們找的是任意兩個結點的最近公共祖先,那麼我們可以考慮這麼兩種種情況 1.兩結點的深度相同.2.兩結點深度不同.第一步都要轉化為情況1,這種可處理的情況。先不考慮其他,我們思考這麼乙個問題 對於兩個深度不同的結點,把深度更深的那個向其父節點迭代,直到這個迭代結點和另乙個結點深度相同,那麼這兩個深度相...
LCA倍增演算法
一.倍增演算法的前期鋪墊 我們記節點v到根的深度為depth v 那麼如果節點w是節點u和節點v的最近公共祖先的話,讓u往上走 depth u depth w 步,讓v往上走 depth v depth w 步,都將走到節點w。因此,我們首先讓u和v中較深的乙個往上走 depth u depth v...