树上距离(lca)(倍增)
Posted SSL_LKJ
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了树上距离(lca)(倍增)相关的知识,希望对你有一定的参考价值。
树上距离
输入样例
1
2 2
1 2 100
1 2
2 1
2
3 2
1 2 10
3 1 15
1 2
3 2
输出样例
1
100
100
2
10
25
解题思路
lca 模板题
用倍增优化
AC代码
#include<iostream>
#include<cstdio>
using namespace std;
int n,m,tot,len[20005],head[20005],deep[20005],f[20005][20];
struct node
{
int to,next,w;
}a[40005];
void add(int x,int y,int z)//建边
{
a[++tot]=(node){y,head[x],z};
head[x]=tot;
}
void ycl()//预处理 f数组
{
for(int j=1;j<16;j++)
for(int i=1;i<=n;i++)
f[i][j]=f[f[i][j-1]][j-1];
}
void dfs(int x,int fa)//深搜
{
deep[x]=deep[fa]+1;
f[x][0]=fa;
for(int i=head[x];i;i=a[i].next)
{
if(a[i].to==fa)continue;
len[a[i].to]=len[x]+a[i].w;
dfs(a[i].to,x);
}
}
int lca(int x,int y)//lca求最近公共祖先
{
if(deep[x]<deep[y])swap(x,y);
for(int i=15;i>=0;i--)
if(deep[f[x][i]]>=deep[y])
x=f[x][i];
if(x==y)return x;
for(int i=15;i>=0;i--)
if(f[x][i]!=f[y][i])
x=f[x][i],y=f[y][i];
return f[x][0];
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<n;i++)
{
int x,y,k;
scanf("%d%d%d",&x,&y,&k);
add(x,y,k);
add(y,x,k);
}
dfs(1,0);
ycl();
for(int i=1;i<=m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
int o=lca(x,y);
printf("%d\\n",len[x]-len[o]+len[y]-len[o]);//求答案
}
return 0;
}
谢谢
以上是关于树上距离(lca)(倍增)的主要内容,如果未能解决你的问题,请参考以下文章
NKOJ P3815 树上的询问 (LCA 倍增)(复习距离倍增)