[LCA 树上最短路 BFS] 距离

Posted 鱼竿钓鱼干

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[LCA 树上最短路 BFS] 距离相关的知识,希望对你有一定的参考价值。

[LCA 树上最短路] 距离

题目

添加链接描述题目链接

思路

多次询问树上最短路。
多次询问最短路考虑floyd,发现必然T,然后考虑题目特点,是要求树上的最短路。
树上两点路径是唯一的,所以只需要计算两点之间距离就可以了。
考虑使用LCA优化
定义dist[i]为节点i到根节点距离
a n s = a b s ( d i s t [ x ] − d i s t [ l c a ] ) + a b s ( d i s t [ y ] − d i s t [ l c a ] ) ans=abs(dist[x]-dist[lca])+abs(dist[y]-dist[lca]) ans=abs(dist[x]dist[lca])+abs(dist[y]dist[lca])
然后就是代码实现,原本尝试用vector存图+dfs维护深度和到根节点距离
但是发现,深度很容易维护,到根节点距离维护是比较复杂的,遍历要找到这个点的来源。
对于需要快速确定来源这一操作,我们可以考虑用bfs代替原本的dfs

另外太久没写vetor了,犯了一个憨憨错误,vector下标操作只能索引已经存在的值(要么都初始化为0),否则会报错

代码

#include<bits/stdc++.h>
using namespace std;
const int N=1e4+10,M=25;
struct Node{
    int p,w;
};
vector<Node>root[N];
int n,m,st,cnt;
int fa[N][M],dep[N],dist[N];
int LG[N];
void prework(){
    LG[1]=0;
    for(int i=2;i<=N;i++)LG[i]=LG[i/2]+1;
}
bool vis[N];
void bfs(){
    queue<int>q;
    q.push(1);dep[1]=1;vis[1]=true;
    while(q.size()){
        int x=q.front();q.pop();
        for(auto to:root[x]){
            int y=to.p,edge=to.w;
            if(vis[y])continue;
            vis[y]=true;
            dep[y]=dep[x]+1;
            dist[y]=dist[x]+edge;
            fa[y][0]=x;
            for(int i=1;i<=20;i++)
                fa[y][i]=fa[fa[y][i-1]][i-1];
            q.push(y);
        }
    }
}
int LCA(int x,int y){
	if(dep[x]<dep[y])swap(x,y);
	while(dep[x]>dep[y])
		x=fa[x][LG[dep[x]-dep[y]]];
	if(x==y)return y;
	for(int i=20;i>=0;i--)
		if(fa[x][i]!=fa[y][i])
			x=fa[x][i],y=fa[y][i];
	return fa[x][0];
}
int main(){
    prework();
    cin>>n>>m;
    for(int i=1;i<n;i++){
        int x,y,k;cin>>x>>y>>k;
        root[x].push_back({y,k});
        root[y].push_back({x,k});
    }
    bfs();
    while(m--){
        int x,y;cin>>x>>y;
        int lca=LCA(x,y);
        cout<<abs(dist[x]-dist[lca])+abs(dist[y]-dist[lca])<<endl;
    }
    return 0;
}

以上是关于[LCA 树上最短路 BFS] 距离的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ2125: 最短路 圆方树(静态仙人掌)

bzoj2125 最短路——仙人掌两点间距离

LCA

[转]LCA 最近公共祖先

最近公共祖先LCA(整理)

bzoj 1295: [SCOI2009]最长距离 暴力+bfs最短路