http://acm.hdu.edu.cn/showproblem.php?pid=2586

课上给的ppt里的模板是错的,wa了一下午orz。最近总是被坑啊。。。

题解:树上两点距离转化为到根的距离之和减去重复部分,相当于前缀和

dis[x] + dis[y] - 2ll * dis[LCA(x, y)]
#define _CRT_SECURE_NO_WARNINGS
#include<cmath>
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<cstring>
#include<stack>
#include<vector>
#include<string.h>
using namespace std;
#define rep(i,t,n) for(int i =(t);i<=(n);++i)
#define per(i,n,t) for(int i =(n);i>=(t);--i)
#define mmm(a,b) memset(a,b,sizeof(a))
#define eps 1e-6
#define pb push_back typedef long long ll; stack <int> dl;
const int maxn=1e5+;
int f[maxn][];
int fa[maxn];
ll dis[maxn];
int dep[maxn]; int n, m;
vector<pair<int,ll> > E[maxn];
void dfs(int rt,int p) { for (int i = ; i < E[rt].size(); i++) {
pair<int,int> v = E[rt][i];
if (v.first == p)continue;
fa[v.first] =rt ;
dep[v.first] =dep[rt]+ ;
dis[v.first] = dis[rt] + v.second;
dfs(v.first, rt);
}
} void Init_LCA() {
for (int j = ; ( << j) <= n; ++j)
for (int i = ; i <= n; ++i)
f[i][j] = -;
for (int i = ; i <= n; ++i) f[i][] = fa[i];
for (int j = ; ( << j) <= n; ++j)
for (int i = ; i <= n; ++i)
if (f[i][j - ] != -)
f[i][j] = f[f[i][j - ]][j - ];
}
int LCA(int x, int y) {
if (dep[x] < dep[y]) swap(x, y);
int i, lg;
for (lg = ; ( << lg) <= dep[x]; ++lg);
--lg;
/// 使x往上走直到和y在同一水平线上;
for (i = lg; i >= ; --i)
if (dep[x] - ( << i) >= dep[y])
x = f[x][i];
if (x == y) return x;
/// 此时x,y在同一水平线上,使x,y同时以相同的速度(2^j)往上走;
for (i = lg; i >= ; --i)
if (f[x][i] != - && f[x][i] != f[y][i])
x = f[x][i], y = f[y][i];
return fa[x];
}
int main()
{
int t;
cin >> t;
while (t--) { cin >> n >> m;
rep(i, , n)E[i].clear();
//mmm(dis, 0); mmm(fa, 0); mmm(f, 0); mmm(dep, 0);
rep(i, , n-) {
int x, y;
ll z;
scanf("%d%d%lld", &x, &y, &z);
//f[x][0] = y;
E[x].push_back(make_pair(y,z));
E[y].push_back(make_pair(x,z));
}
dis[] = ;
//fa[1] = 1;
//dep[1] = 0;
dfs(, -);
Init_LCA();
rep(i, , m) {
int x, y;
scanf("%d%d", &x, &y);
printf("%lld\n", dis[x] + dis[y] - 2ll * dis[LCA(x, y)]); }
//cout << endl;
}
cin >> n;
return ;
}/*
2
5 2
1 2 10
2 3 10
3 4 10
4 5 10
1 5
5 3 */

模板倍增LCA 求树上两点距离 hdu2586的更多相关文章

  1. How far away ? LCA求树上两点距离

    How far away ? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

  2. Codeforces Round #620 (Div. 2)E(LCA求树上两点最短距离)

    LCA求树上两点最短距离,如果a,b之间距离小于等于k并且奇偶性与k相同显然YES:或者可以从a先走到x再走到y再走到b,并且a,x之间距离加b,y之间距离+1小于等于k并且奇偶性与k相同也输出YES ...

  3. cogs 2450. 距离 树链剖分求LCA最近公共祖先 快速求树上两点距离 详细讲解 带注释!

    2450. 距离 ★★   输入文件:distance.in   输出文件:distance.out   简单对比时间限制:1 s   内存限制:256 MB [题目描述] 在一个村子里有N个房子,一 ...

  4. LCA - 求任意两点间的距离

    There are n houses in the village and some bidirectional roads connecting them. Every day peole alwa ...

  5. 洛谷P2633 Count on a tree(主席树,倍增LCA,树上差分)

    洛谷题目传送门 题目大意 就是给你一棵树,每个点都有点权,每次任意询问两点间路径上点权第k小的值(强制在线). 思路分析 第k小......又是主席树了.但这次变成树了,无法直接维护前缀和. 又是树上 ...

  6. hdu6446 网络赛 Tree and Permutation(树形dp求任意两点距离之和)题解

    题意:有一棵n个点的树,点之间用无向边相连.现把这棵树对应一个序列,这个序列任意两点的距离为这两点在树上的距离,显然,这样的序列有n!个,加入这是第i个序列,那么这个序列所提供的贡献值为:第一个点到其 ...

  7. HDU 2586 /// tarjan离线求树上两点的LCA

    题目大意: 询问一棵树里 u 到 v 的距离 可由 dis[ u到根 ] + dis[ v到根 ] - 2*dis[ lca(u,v) ] 得到 https://blog.csdn.net/csyzc ...

  8. Codeforces 1304E. 1-Trees and Queries 代码(LCA 树上两点距离判奇偶)

    https://codeforces.com/contest/1304/problem/E #include<bits/stdc++.h> using namespace std; typ ...

  9. 2018中国大学生程序设计竞赛 - 网络选拔赛 1009 - Tree and Permutation 【dfs+树上两点距离和】

    Tree and Permutation Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Oth ...

随机推荐

  1. Win10 设置窗口背景色

    Win10 的窗口背景色不能像Win7那样通过修改Windows的"窗口"配置来生效,只能是通过修改注册表的信息来修改Win10的窗口色. 1. 通过注册表来修改默认的窗口背景色( ...

  2. css组合选择器

    组合选择器:1,后代选择器 .main h2 {...}, 使用空格表示 IE6+2,子选择器 .main>h2 {...}, 使用 > 表示 IE7+3,兄弟选择器 h2+p {...} ...

  3. GCD使用:让程序在后台较长久的运行(UIBackgroundTaskIdentifier )

        在没有使用GCD时,当app被按home键退出后,app仅有最多5秒钟的时候做一些保存或清理资源的工作.但是在使用GCD后,app最多有10分钟的时间在后台长久运行.这个时间可以用来做清理本地 ...

  4. Android源码阅读笔记二 消息处理机制

    消息处理机制: .MessageQueue: 用来描述消息队列2.Looper:用来创建消息队列3.Handler:用来发送消息队列 初始化: .通过Looper.prepare()创建一个Loope ...

  5. 【Android】Eclipse性能优化,快捷方式,文档注释

    快捷方式 方法注释的快捷键:ALT + SHIFT +J 格式化:Ctrl+Shift+F 把当前选中的文本全部变味大写:Ctrl+Shift+X 把当前选中的文本全部变为小写:Ctrl+Shift+ ...

  6. 【转】Django中使用POST方法获取POST数据

    1.获取POST中表单键值数据 如果要在django的POST方法中获取表单数据,则在客户端使用JavaScript发送POST数据前,定义post请求头中的请求数据类型: xmlhttp.setRe ...

  7. 【emWin】例程二十:窗口对象——Dropdown

    简介: DROPDOWN 小工具用于从具有若干栏的列表中选择一个元素,它以非打开状态显示当前选择的项目.如果用户打开DROPDOWN 小工具,就会出现一个选择新项目的LISTBOX. 触摸校准(上电可 ...

  8. Guava学习笔记(二):基础(Joiner,Objects,Splitter及Strings)

    添加Maven依赖 JoinerTest import com.google.common.base.Joiner; import org.junit.Assert; import org.junit ...

  9. [Object Tracking] Contour Detection through OpenCV

    利用OpenCV检测图像中的长方形画布或纸张并提取图像内容 - 阅读笔记 相对来说,如下链接是此文的高阶方案版本,做对比是极好的. [Object Tracking] Contour Detectio ...

  10. [Converge] Weight Initialiser

    From: http://www.cnblogs.com/denny402/p/6932956.html [, ] fully connected w = tf.Variable(tf.truncat ...