洛谷P4281:https://www.luogu.org/problemnew/show/P4281

思路

答案所在的点必定是个人所在点之间路径上的一点

本蒟蒻一开始的想法是:先求出2个点之间的LCA 再求出此LCA和第3个点的LCA

但是没有考虑到有可能答案所在点可能比2个点之间的LCA深度更深

因为两点之间的LCA是两点共同能到达的深度最浅的一个点

所以我们可以考虑:

设a=LCA(x,y) 此时x和y到a点为最小花费 则此时z到a的花费可以用LCA(a,z)来计算

因此我们分别计算3种情况并取最小值即可

设d为树的深度 a为x和y的LCA b为a与z的LCA 从x到a y到a 分别花费d[x]-d[a]和d[y]-d[a] 从z到a花费d[z]+d[a]-2*d[b]

ans=max(d[x]+d[y]+d[z]-d[a]-2*d[b])

代码

#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
#define maxn 500050
#define INF 1e9+7
int n,m,cnt,ans,a,b,k,x,y,z;
int h[maxn],dep[maxn],f[maxn][];
struct Edge
{
int next;
int to;
}e[maxn<<];
void add(int u,int v)
{
e[++cnt].to=v;
e[cnt].next=h[u];
h[u]=cnt;
}
void deal(int u,int fa)//常规预处理
{
dep[u]=dep[fa]+;
for(int i=;i<=;i++)
{
f[u][i]=f[f[u][i-]][i-];
}
for(int i=h[u];i;i=e[i].next)
{
int v=e[i].to;
if(v==fa) continue;
f[v][]=u;
deal(v,u);
}
}
int lca(int x,int y)//常规LCA
{
if(dep[x]<dep[y]) swap(x,y);
for(int i=;i>=;i--)
{
if(dep[f[x][i]]>=dep[y]) x=f[x][i];
if(x==y) return x;
}
for(int i=;i>=;i--)
{
if(f[x][i]!=f[y][i])
{
x=f[x][i];
y=f[y][i];
}
}
return f[x][];
}
void check()
{
int t=dep[x]+dep[y]+dep[z]-dep[a]-*dep[b];//计算每种情况的ans
if(t<ans)//如果当前值小于原ans 则替换
{
ans=t;
k=a;//k为最后的位置
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<n;i++)
{
scanf("%d%d",&x,&y);
add(x,y);
add(y,x);
}
deal(,);//预处理
for(int i=;i<=m;i++)
{
ans=INF;//初始化
scanf("%d%d%d",&x,&y,&z);
a=lca(x,y);//三种情况分别计算
b=lca(a,z);
check();
a=lca(x,z);
b=lca(a,y);
check();
a=lca(z,y);
b=lca(a,x);
check();
printf("%d %d\n",k,ans);
}
}

最新文章

  1. 一图搞定【实战Java高并发程序设计】
  2. Android音视频之MediaRecorder音视频录制
  3. 细说angular Form addControl方法
  4. hibernate......1、2级缓存
  5. Java直接插入排序
  6. user-agent中的mozilla
  7. 一些网摘的hpc材料
  8. Google Play市场考察报告-2
  9. java实现二叉树的相关操作
  10. 微信小程序开源项目库汇总
  11. MyBatis 源码分析——SqlSession接口和Executor类
  12. Excel制作多选下拉框代码以及图示
  13. Java基础总结--异常处理机制
  14. windows下将mysql加入环境变量
  15. 基于element-tree-table树型表格点击节点请求数据展开树型表格
  16. 使用PreparedStatement 查询一条数据 封装成一个学生的Student1对象
  17. sublime text 入门
  18. poj 3207(2-SAT+SCC)
  19. hdu 1151 Air Raid - 二分匹配
  20. (转)mblog解读(一)

热门文章

  1. Java 方法重载和多态
  2. Linux From Scratch(从零开始构建Linux系统,简称LFS)(二)
  3. UNIX 5种I/O模型
  4. 读ios开发有感——建立APP开发体系
  5. java 文件的上传和下载
  6. easyui window窗口 随body的滚动条 滚动
  7. easyui grid 里的可编辑text 加清空图标
  8. Java中的深拷贝和浅拷贝(转载)
  9. Creator4.2建模心得与技巧1——树的建立与跟随摄像机旋转
  10. JDBC连接数据库方法的封装,以及查询数据方法的封装