LCA Tarjan及倍增模板 POJ 1330

2021-07-26 16:37:59 字數 1143 閱讀 9035

我目前學會的兩種求lca的演算法:

a、tarjan演算法(離線演算法)

演算法思路:

1、從根結點開始dfs。

2、遍歷點x的所有子節點。

3、從某乙個子節點y返回x時,要在並查集中把x,y所在的兩棵子樹合併,且根節點為點x所在子樹的根節點。

4、離開結點x前,要看看是否有與x相關的詢問(x,y),如果有且結點y已被訪問過,(x,y)的lca就是並查集中點y所在子樹的根節點。

注意各個步驟實現的順序:遞迴 - > 合併 - > 查詢詢問 - > 返回

**:

#include#include#includeusing namespace std;

int n;

vectora[10005];

int ask1,ask2;

bool use1,use2;

int fa[10005]= ;

int find(int x)

return fa[x]=find(fa[x]);

}bool flag=false;

void lca(int x) ;

int deep[10005]= ;

void dfs(int x,int fa)

for(int i=0; i=0; i--)

} if(x==y) return x;

for(int i=15; i>=0; i--)

} return anc[x][0];

}int main() ;

memset(root,true,sizeof(root));

scanf("%d",&n);

for(int i=1; i<=n; i++)

memset(anc,0,sizeof(anc));

memset(deep,0,sizeof(deep));

deep[0]=-1;

for(int i=1; i<=n-1; i++)

for(int i=1; i<=n; i++)

} int ask1,ask2;

scanf("%d%d",&ask1,&ask2);

printf("%d\n",lca(ask1,ask2));

} return 0;

}

演算法 LCA tarjan 倍增

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

倍增LCA模板

注意!本篇題解不適合初學lca的同學學習,因為我講的很爛很不清楚。倍增,顧名思義,就是成倍增加的意思。我們知道,任何乙個數字都可以表示成二進位制。那麼對於一條長度為n的鏈,我們總是可以跳大概logn次到達最後。對於鏈上任意一點,我們都可以在大概logn的複雜度下詢問到,其實倍增的思路就是二分,和快速...

樹上倍增(模板)

題意 給出結點數為n的一棵樹,每個結點有權值 m 次詢問,對於每次詢問 a,b,l,r,求出結點a到結點b路徑經過的點中,權值在在區間 l,r 內的權值和。sample input 5 31 2 1 3 2 1 22 4 3 12 5 4 5 1 3 1 1 1 1 3 5 2 3 sample o...