[luogu 3379]最近の公的祖先(樹上倍増LCAを求める)
11487 ワード
最近の公共の祖先を求める.
問題を解く鍵:3つの方法、1、st表2、倍増法3、tarjan
今回は倍増テンプレートを使います(1つ目、2つ目は純粋に習慣です)
2、おなじみのツリーdp方式
転載先:https://www.cnblogs.com/elpsycongroo/p/10352437.html
問題を解く鍵:3つの方法、1、st表2、倍増法3、tarjan
今回は倍増テンプレートを使います(1つ目、2つ目は純粋に習慣です)
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;
int n,m,root,cnt,u,v,head[500005],dep[500005],fa[500005][21];
struct edge{
int nxt;
int to;
}e[1000005];
void add_edge(int u,int v){//
e[cnt].to=v;
e[cnt].nxt=head[u];
head[u]=cnt++;
}
void dfs(int u){
for(int i=1;(1<){
fa[u][i]=fa[fa[u][i-1]][i-1];
}
for(int i=head[u];~i;i=e[i].nxt){
int v=e[i].to;
if(v==fa[u][0]) continue;
fa[v][0]=u;
dep[v]=dep[u]+1;
dfs(v);
}
}
int lca(int u,int v){
if(dep[u]<dep[v]) swap(u,v);
int d=dep[u]-dep[v];
for(int i=0;(1<if(d&(1<// ,
if(u==v) return u;
for(int i=20;i>=0;i--){
if(fa[u][i]!=fa[v][i]){
u=fa[u][i];
v=fa[v][i];
}
}
return fa[u][0];
}
int main(){
memset(head,-1,sizeof head);
scanf("%d%d%d",&n,&m,&root);
for(int i=1;i){
scanf("%d%d",&u,&v);
add_edge(u,v);
add_edge(v,u);
}
dfs(root);
while(m--){
scanf("%d%d",&u,&v);
printf("%d
",lca(u,v));
}
return 0;
}
2、おなじみのツリーdp方式
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;
int n,m,root,cnt,u,v,head[500005],dep[500005],par[500005][21];
struct edge{
int nxt;
int to;
}e[1000005];
void add_edge(int u,int v){//
e[cnt].to=v;
e[cnt].nxt=head[u];
head[u]=cnt++;
}
void dfs(int u,int fa){
for(int i=1;(1<){
par[u][i]=par[par[u][i-1]][i-1];
}
for(int i=head[u];~i;i=e[i].nxt){
int v=e[i].to;
if(v==fa) continue;
par[v][0]=u;
dep[v]=dep[u]+1;
dfs(v,u);
}
}
int lca(int u,int v){
if(dep[u]<dep[v]) swap(u,v);
int d=dep[u]-dep[v];
for(int i=0;(1<if(d&(1<// ,
if(u==v) return u;
for(int i=20;i>=0;i--){
if(par[u][i]!=par[v][i]){
u=par[u][i];
v=par[v][i];
}
}
return par[u][0];
}
int main(){
memset(head,-1,sizeof head);
scanf("%d%d%d",&n,&m,&root);
for(int i=1;i){
scanf("%d%d",&u,&v);
add_edge(u,v);
add_edge(v,u);
}
dfs(root,-1);
while(m--){
scanf("%d%d",&u,&v);
printf("%d
",lca(u,v));
}
return 0;
}
転載先:https://www.cnblogs.com/elpsycongroo/p/10352437.html