• 点的距离


    https://loj.ac/problem/10130

    题目描述

      给出一棵(n)个点的树,有(Q)个询问,每次询问节点(x、y)之间的距离。

    思路

      这是一棵不带权树,所以我们只要知道了(x、y)(LCA)就可以求出两点间的距离。求(LCA)的方法有很多,这里主要讲倍增求(LCA),这种方法比较好理解也比较简单,而且可以满足大部分题目的需要(常数最小的为树剖)。我们记录(f[i][j])表示(i)(2^j)祖先是谁,我们可以一遍(dfs)处理处这个数组。接下来对于每个询问的点,我们考虑先把(x、y)跳到同一高度,这个过程可以倍增实现。接下来再把(x、y)同时往上跳,遇到第一个相同的点即为(LCA)

    代码

    #include <bits/stdc++.h>
    using namespace std;
    const int N=1e5+10;
    
    int nxt[N<<1],head[N],to[N<<1],tot;
    void add_edge(int x,int y)
    {
    	nxt[++tot]=head[x];
    	head[x]=tot;
    	to[tot]=y;
    }
    
    int f[N][22],dep[N];
    void dfs(int u,int fa)
    {
    	dep[u]=dep[fa]+1;
    	for(int i=0;i<=19;i++)
    		f[u][i+1]=f[f[u][i]][i];
    	for(int i=head[u];i;i=nxt[i])
    	{
    		int v=to[i];
    		if(v==fa)continue ;
    		f[v][0]=u;
    		dfs(v,u);
    	}
    }
    int LCA(int x,int y)
    {
    	if(dep[x]<dep[y])swap(x,y);
    	for(int i=19;i>=0;i--)
    	{
    		if(dep[f[x][i]]>=dep[y])x=f[x][i];
    		if(x==y)return y;
    	}
    	for(int i=19;i>=0;i--)
    		if(f[x][i]!=f[y][i])
    		{
    			x=f[x][i];
    			y=f[y][i];
    		}
    	return f[x][0];
    }
    
    int read()
    {
    	int res=0,w=1;
    	char ch=getchar();
    	while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9'){res=(res<<3)+(res<<1)+(ch^48);ch=getchar();}
    	return res*w;
    }
    void write(int x)
    {
    	if(x<0){putchar('-');x=-x;}
    	if(x>9)write(x/10);
    	putchar(x%10+'0');
    }
    void writeln(int x)
    {
    	write(x);
    	putchar('
    ');
    }
    
    int main() 
    {
    	int n=read();
    	for(int i=1;i<n;i++)
    	{
    		int x=read(),y=read();
    		add_edge(x,y);add_edge(y,x);
    	}
    	dfs(1,0);
    	int q=read();
    	while(q--)
    	{
    		int x=read(),y=read();
    		int lca=LCA(x,y);
    		writeln(dep[x]+dep[y]-2*dep[lca]);
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    golang ssh 相关
    javascript 常用正则表达式收集
    Mac下 shell文件双击可执行怎么写
    Python常用插件之BeautifulSoup4使用
    Python常用插件之Requests使用
    JavaScript学习-WeakSet
    javascript学习-Set
    Vue-大型项目下路由的模块拆分
    360兼容模式ie10不支持includes方法
    360兼容模式ie10及以下版本map对象和Set对象没有定义
  • 原文地址:https://www.cnblogs.com/fangbozhen/p/11788361.html
Copyright © 2020-2023  润新知