树上倍增 hdu 2586
代码:
#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。*/
树上倍增 hdu 2586的更多相关文章
- HDU 4822 Tri-war(LCA树上倍增)(2013 Asia Regional Changchun)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4822 Problem Description Three countries, Red, Yellow ...
- hdu 2586 How far away ?倍增LCA
hdu 2586 How far away ?倍增LCA 题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=2586 思路: 针对询问次数多的时候,采取倍增 ...
- hdu 2586 How far away
How far away ? Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) T ...
- 树上倍增求LCA及例题
先瞎扯几句 树上倍增的经典应用是求两个节点的LCA 当然它的作用不仅限于求LCA,还可以维护节点的很多信息 求LCA的方法除了倍增之外,还有树链剖分.离线tarjan ,这两种日后再讲(众人:其实是你 ...
- 洛谷P3379lca,HDU2586,洛谷P1967货车运输,倍增lca,树上倍增
倍增lca板子洛谷P3379 #include<cstdio> struct E { int to,next; }e[]; ],anc[][],log2n,deep[],n,m,s,ne; ...
- LCA(最近公共祖先)--tarjan离线算法 hdu 2586
HDU 2586 How far away ? Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/ ...
- Codevs 2370 小机房的树 LCA 树上倍增
题目描述 Description 小机房有棵焕狗种的树,树上有N个节点,节点标号为0到N-1,有两只虫子名叫飘狗和大吉狗,分居在两个不同的节点上.有一天,他们想爬到一个节点上去搞基,但是作为两只虫子, ...
- NOIP2013 货车运输 (最大生成树+树上倍增LCA)
死磕一道题,中间发现倍增还是掌握的不熟 ,而且深刻理解:SB错误毁一生,憋了近2个小时才调对,不过还好一遍AC省了更多的事,不然我一定会疯掉的... 3287 货车运输 2013年NOIP全国联赛提高 ...
- HDU - 2586 How far away ?(LCA模板题)
HDU - 2586 How far away ? Time Limit: 1000MS Memory Limit: 32768KB 64bit IO Format: %I64d & ...
随机推荐
- 服务发现和注册和Eureka
一 Spring Cloud特点 # 约定优于配置 # 开箱即用,快速启动 # 适用于各种环境,可以部署在PC server或者 云环境 # 轻量级的组件 # 组件的支持很丰富,功能齐全 # 选型中立 ...
- javascript常用经典算法实例详解
javascript常用经典算法实例详解 这篇文章主要介绍了javascript常用算法,结合实例形式较为详细的分析总结了JavaScript中常见的各种排序算法以及堆.栈.链表等数据结构的相关实现与 ...
- Vue手把手教你撸一个 beforeEnter 钩子函数
地址 :https://www.jb51.net/article/138821.htm 地址 :https://www.jb51.net/article/108964.htm
- leetcode.数组.667优美的排列II-Java
1. 具体题目 给定两个整数 n 和 k,你需要实现一个数组,这个数组包含从 1 到 n 的 n 个不同整数,同时满足以下条件:① 如果这个数组是 [a1, a2, a3, ... , an] ,那么 ...
- MUI对话框使用
一.alert告警框 用法 .alert(message,title,btnvalue,callback[,type]); document.getElementById("noclick& ...
- lamp搭建
一.准备工作1.配置本地YUM源 2.关闭selinux以及iptables service iptables stop chkconfig iptables off setenforce 0 vim ...
- 分布式-技术专区-Redis分布式锁实现-第一步
承接前面一篇Redis分布式锁的原理介绍 https://www.cnblogs.com/liboware/p/11921759.html 我们针对于实现方案进行接下来上篇进行重新的规划和定义以及完善 ...
- C#5.0 异步编程 Async和Await--异步方法的规范和注意事项
要些异步方法要注意一下几点: 异步方法的返回值有三种: 1.没有任何返回值的void 2.返回一个Task任务的Task,可以获得该异步方法的执行状态 3.返回Task<T> 可以获得异步 ...
- 61. File类
IO技术主要作用是解决设备与设备之间的数据传输问题.比如:硬盘---->内存 内存的数据---->硬盘上 把硬盘的数据------>内存中 IO技术的应用场景: ...
- Ubuntu图形界面和终端界面切换快捷键
Ctrl+Alt+F1可以从图形界面切换到终端界面. Ctrl+Alt+F7可以从终端界面退出来,重新回到图形界面