1>dfs遍歷時經過的所有節點的位置
2>每個節點第一次出現的位置
3>每個節點的深度
查詢時先取出兩個節點的位置求出這兩個位置間的深度最小的節點
這個節點就是lca
code:
//by menteur_hxy 2068ms
#include
#include
#include
using
namespace
std;
const
int inf=0x3f3f3f3f;
const
int max=500110;
int n,qu,root,cnt;
int head[max],ver[max*2],first[max],log[max*2],deep[max],f[max*2][21];
struct edgesedge[max*2+5];
void add(int x,int y)
void dfs(int u,int pre)
}}void st()
int k=log[cnt];
for(int j=1;j<=k;j++)
for(int i=1;i+(1
<1
<=cnt;i++)
}int rmq(int l,int r)
int ask(int x,int y)
int main()
cnt=0;
dfs(root,-1);
// for(int i=1;i<=cnt;i++) coutfor(int i=1;i<=qu;i++)
return
0;}
同樣需要dfs,不過只需求出深度和每個節點的父親
現在設f[i][j] 表示i的第2^j個祖先 (eg:f[i][0] 即為i的父親)
所以顯然有 f[i][j]=f[f[i][j-1]][j-1] (i的第2^j-1個祖先的第2^j-1個祖先是i的2^j個祖先)
查詢兩節點時,先將深度較大的節點向上移動直到與另乙個節點深度相同,判斷此時兩節點是否相同如果不同,就從大到小列舉嘗試往上跳直到兩節點父親相同此時父親就是lca
code:
//by menteur_hxy 1860ms
#include
#include
#include
#include
#include
#include
#include
using
namespace
std;
const
int max=500010;
int n,qu,root,cnt;
int head[max],deep[max],f[max][20];
/*f[i][j] i的第2^j個祖先
*/struct edgesedge[max*2];
void add(int x,int y)
void dfs_bz(int cur)
}}void init()
int lca_bz(int x,int y)
return f[x][0];
}else
return x;
}int main()
f[root][0]=-1;
dfs_bz(root);
init();
for(int i=1;i<=qu;i++)
return
0;}
先記錄查詢的問題
進行dfs,每次在節點(u)返回前查詢與它構成問題的所有節點(v),如果其中有之前已經遍歷過的節點(vis[v]=true),則這兩個節點的lca為find(v),所有v都查過後,將它與它的父節點的集合合併,之後返回。
code;
//by menteur_hxy 912ms
#include
#include
#include
using
namespace
std;
const
int max=500010;
int n,qu,root,cnt;
int head[max],f[max],head_[max],vis[max],ans[max];
struct edgesedge[max*2],edge_[max*2];
void add(int x,int y)
void add_(int x,int y)
int find(int x)
void tarjan(int u,int pre)
}for(int i=head_[u];i;i=edge_[i].next)
}int main()
f[n]=n;
cnt=0;
for(int i=1;i<=qu;i++)
tarjan(root,-1);
for(int i=1;i<=qu;i++)
printf("%d\n",ans[i]);
return
0;}
模板 最近公共祖先(LCA)
題自洛谷 如題,給定一棵有根多叉樹,請求出指定兩個點直接最近的公共祖先。輸入格式 第一行包含三個正整數n m s,分別表示樹的結點個數 詢問的個數和樹根結點的序號。接下來n 1行每行包含兩個正整數x y,表示x結點和y結點之間有一條直接連線的邊 資料保證可以構成樹 接下來m行每行包含兩個正整數a b...
模板 lca 最近公共祖先
lca hljs cpp include include using namespace std const int maxn 500001 int n,m,gen,x,y struct edgeedge 2 maxn int deep maxn fa maxn 20 deep記錄每個點的深度,fa...
最近公共祖先 LCA 模板
lca即最近公共祖先,是指 在有根樹中,找出某兩個結點u和v最近的公共祖先。時間複雜度o nlogn m n 步驟 1.將樹看作乙個無向圖,從根節點開始深搜,得到乙個遍歷序列。2.在x y區間中利用rmq演算法找到深度最小返回其下標。可以上洛谷找模板題測試 include include inclu...