我目前學會的兩種求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...