参考博客:

代码:

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<math.h>
#include<string.h>
using namespace std;
const int max_=8e4+;
int depth[max_];//节点深度
int gw[max_][];//第 i 点到2^j父亲的距离
int fa[max_][];//第 i 点的2^j父亲
bool vis[max_];//标记数组
int tot,N;
struct Tree//树
{
int to;
int w;
int next;
}a[max_*];
int edge[max_*];
void add_edge(int x,int y,int w)//建树
{
a[tot].to=y;
a[tot].w=w;
a[tot].next=edge[x];
edge[x]=tot++;
}
void dfs(int now,int deep)//dfs预处理
{
if(vis[now]==)
{
vis[now]=;
depth[now]=deep;//记录节点的深度
}
for(int i=edge[now];i!=-;i=a[i].next)
{
int to=a[i].to;
if(vis[to])
continue;
int w=a[i].w;
gw[to][]=w;//to到父亲的距离
fa[to][]=now;//to的父亲节点
dfs(to,deep+);
}
}
void LCA_init(int n)//预处理
{
for(int i=;i<=n;i++)
for(int j=;j<=N;j++)
{
fa[i][j]=fa[fa[i][j-]][j-];
gw[i][j]=gw[fa[i][j-]][j-]+gw[i][j-];
}
}
int LCA_Q(int u,int v)
{
int ans=;//距离
if(depth[u]<depth[v])
swap(u,v);//保证大减小
int k;
k=depth[u]-depth[v];
for(int i=;(<<i)<=k;i++)
{
if((<<i)&k)
ans+=gw[u][i],u=fa[u][i];
}
if(u==v)
return ans;//找到了就退出
for(int i=N;i>=;i--)
{
if(fa[u][i]!=fa[v][i])
{
ans+=gw[u][i],
ans+=gw[v][i];
u=fa[u][i],
v=fa[v][i];
}
}
return ans+=gw[v][]+gw[u][];
}
void init(int n)//初始化
{
memset(vis,,sizeof(vis));
tot=;
N=(int)(log(n+0.0)/log());
memset(edge,-,sizeof(edge));
}
int main()
{
int t;
cin>>t;
while(t--)
{
int n,m;
scanf("%d %d",&n,&m);
init(n);
for(int i=;i<n-;i++)
{
int u,v,w;
scanf("%d %d %d",&u,&v,&w);
add_edge(u,v,w);
add_edge(v,u,w);
}
dfs(,);
LCA_init(n);
while(m--)
{
int u,v;
scanf("%d %d",&u,&v);
int L=LCA_Q(u,v);
printf("%d\n",L);
}
/* for(int i=1;i<=n;i++)
printf("%d ",fa[i][2]);*/
}
}
/*
13 2
1 2 1
1 3 1
1 4 1
2 5 1
3 6 1
6 10 1
6 11 1
10 13 1
4 7 1
4 8 1
4 9 1
8 12 1
*/
/* for(int x=max0;x>=0;x--) //注意!此处循环必须是从大到小!因为我们应该越提越“精确”,
if(fa[u][x]!=fa[v][x]) //如果从小到大的话就有可能无法提到正确位置,自己可以多想一下
{
u=fa[u][x];
v=fa[v][x];
}
return fa[u][0]; //此时u、v的第一个父亲就是LCA。*/

最新文章

  1. Excel&mdash;&mdash;MATCH函数
  2. 爬虫2 url管理器 url_manager.py
  3. 从源代码分析Android-Universal-Image-Loader图片下载技巧
  4. SymmetricDS 数据库双向同步开源软件入门
  5. LeetCode Reverse Nodes in k-Group 每k个节点为一组,反置链表
  6. 记录一下Swift3.0的一些代码格式的变化
  7. cocos2d-x 节点操作 --&gt;J2ME
  8. zoj 2734 Exchange Cards【dfs+剪枝】
  9. [置顶] js正则表达式的使用
  10. 在hibernate中使用SQL语句
  11. Linux的selinux
  12. Office Add-in 设计规范与最佳实践
  13. DALI 2.0解码模块
  14. JAVA 调用 R 语言之升华篇
  15. 【Unity3D与23种设计模式】建造者模式(Builder)
  16. java程序员技术范围
  17. 2019.01.19 codeforces915E.Physical Education Lessons(ODT)
  18. Vue2.0-token权限处理
  19. JS判断图片加载完成方法
  20. MongoDB 投影

热门文章

  1. TP5.1/TP框架的访问控制,访问不存在的模块、控制器、方法等控制
  2. python基础【第四篇】
  3. Linux部分常用命令详解(二)
  4. 36-python基础-python3-字典与列表的区别
  5. How to easily Detect Objects with Deep Learning on Raspberry Pi
  6. Linux安装配置Nginx服务器
  7. 2019计蒜之道初赛第3场-阿里巴巴协助征战SARS 费马小定理降幂
  8. PHP-删除排序数组中的重复项
  9. mongodb的学习 (3)
  10. Hadoop(二)HDFS