LCA RMQ倍增演算法 codevs 1036

2021-07-15 08:07:28 字數 1562 閱讀 3513

參考於

/*題為codevs1036

假設有n個城鎮,首都編號為1,商人從首都出發,其他各城鎮之間都有道路連線,任意兩個城鎮之間如果有直連道路,在他們之間行駛需要花費單位時間。該國公路網路發達,

從首都出發能到達任意乙個城鎮,並且公路網路不會存在環。

你的任務是幫助該商人計算一下他的最短旅行時間。

e.g.

input

51 2 1 5 3 5 4 5

4 1 3 2 5

output

7 */

#include

#include

#include

#include

using namespace std;

int n,m;

int head[30001],next[60001],to[60001],sum;

int deep[30001];

int f[30001][20];

int s,t;

int ans_lca,ans;

void dfs(int u)//遍歷所有節點; }}

void init()

}return f[s][0];

}int main()

for(int i=1;i1) s=t;

scanf("%d",&t);

ans_lca=lca(s,t);

ans+=deep[s]+deep[t]-2*deep[ans_lca];

}printf("%d",ans);

/*高階codevs2370*/

#include

#include

#include

using namespace std;

int n,m,ans_lca;

int head[50005],next[100005],to[100005],w[100005],sum;

int deep[50005];

int f[50005][20],d[50005][20];

int s,t;

void dfs(int u)

}void init()

return f[a][0];

}int tot(int a,int b)

,minv[n][pow],diff[n][pow]=,dife[n][pow]=,q[n];

//  diff:順區間最大差

//  dife:逆區間最大差

void dfs(int x,int fa)

if(d[a]=0;i--)

if(f[a][i]!=f[b][i])

else

a=f[a][i],b=f[b][i];

}total=max(total,maxn-minn);

if(!flag)

else

}return total;

}int main()

for(i=0;idfs(g[1][i],1);

scanf("%d",&m);

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

return 0;

}

Algorithm LCA(倍增演算法)

基本思想 參考 from lanshui yang deep i 表示 i節點的深度,fa i,j 表示 i 的 2 j 即2的j次方 倍祖先,那麼fa i 0 即為節點i 的父親,然後就有乙個遞推式子 fa i,j fa fa i,j 1 j 1 可以這樣理解 設tmp fa i,j 1 tmp2...

LCA倍增演算法

一.倍增演算法的前期鋪墊 我們記節點v到根的深度為depth v 那麼如果節點w是節點u和節點v的最近公共祖先的話,讓u往上走 depth u depth w 步,讓v往上走 depth v depth w 步,都將走到節點w。因此,我們首先讓u和v中較深的乙個往上走 depth u depth v...

演算法 LCA tarjan 倍增

呃,這個常用但是我一直不會 tar jan tarjan ta rjan tarjan 演算法基於 dfs 在 dfs 的過程中,對於每個節點位置的詢問做出相應的回答。tarjian,邊建邊 邊回答問題 include include include using namespace std intn...