模板倍增LCA 求树上两点距离 hdu2586
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的更多相关文章
- How far away ? LCA求树上两点距离
How far away ? Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)To ...
- 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 ...
- cogs 2450. 距离 树链剖分求LCA最近公共祖先 快速求树上两点距离 详细讲解 带注释!
2450. 距离 ★★ 输入文件:distance.in 输出文件:distance.out 简单对比时间限制:1 s 内存限制:256 MB [题目描述] 在一个村子里有N个房子,一 ...
- LCA - 求任意两点间的距离
There are n houses in the village and some bidirectional roads connecting them. Every day peole alwa ...
- 洛谷P2633 Count on a tree(主席树,倍增LCA,树上差分)
洛谷题目传送门 题目大意 就是给你一棵树,每个点都有点权,每次任意询问两点间路径上点权第k小的值(强制在线). 思路分析 第k小......又是主席树了.但这次变成树了,无法直接维护前缀和. 又是树上 ...
- hdu6446 网络赛 Tree and Permutation(树形dp求任意两点距离之和)题解
题意:有一棵n个点的树,点之间用无向边相连.现把这棵树对应一个序列,这个序列任意两点的距离为这两点在树上的距离,显然,这样的序列有n!个,加入这是第i个序列,那么这个序列所提供的贡献值为:第一个点到其 ...
- HDU 2586 /// tarjan离线求树上两点的LCA
题目大意: 询问一棵树里 u 到 v 的距离 可由 dis[ u到根 ] + dis[ v到根 ] - 2*dis[ lca(u,v) ] 得到 https://blog.csdn.net/csyzc ...
- Codeforces 1304E. 1-Trees and Queries 代码(LCA 树上两点距离判奇偶)
https://codeforces.com/contest/1304/problem/E #include<bits/stdc++.h> using namespace std; typ ...
- 2018中国大学生程序设计竞赛 - 网络选拔赛 1009 - Tree and Permutation 【dfs+树上两点距离和】
Tree and Permutation Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Oth ...
随机推荐
- SVProgressHUD在viewDidLoad里无法显示的bug
两年前已经开始讨论,至今没有解决方案.https://github.com/samvermette/SVProgressHUD/issues/54 [SVProgressHUD show] 的逻辑要放 ...
- 6-9-哈夫曼树(HuffmanTree)-树和二叉树-第6章-《数据结构》课本源码-严蔚敏吴伟民版
课本源码部分 第6章 树和二叉树 - 哈夫曼树(HuffmanTree) ——<数据结构>-严蔚敏.吴伟民版 源码使用说明 链接☛☛☛ <数据结构-C语言版> ...
- Asp.Net 简繁转换
帮助类 /// <summary> /// 中文字符工具类 /// </summary> public static class ChineseStringUtility { ...
- 导出不带.svn的文件夹或者是不含.class的文件
转载自:http://blog.csdn.net/z278718149/article/details/21537395 如何导出不带.svn的文件夹或者是不含.class的文件 在工作环境中,有的时 ...
- 在android 上 使用 rxjava 入门篇
什么是 rxJava? RxJava is a Java VM implementation of Reactive Extensions: a library for composing async ...
- Halcon 2D测量
* This program shows how to detect the edges of a diamond * with subpixel accuracy and calculate the ...
- CTimeSpan
要获取两个时间差,如两个CTime的时间差,可以使用MFC中的CTimeSpan类. CTime time1 = CTime::GetCurrentTime(); CTime time2 = CTim ...
- Java JPA小记
什么是JPA JPA之于ORM(持久层框架,如MyBatis.Hibernate等)正如JDBC之于数据库驱动. JDBC是Java语言定义的一套标准,规范了客户端程序访问关系数据库(如MySQL.O ...
- azkaban在centos下的部署安装
azkaban 是一个用Java开发的开源调度工具workflow. 下面介绍具体安装过程,我这里使用的版本是3.43.0,使用的是solo运行模式. 编译 git clone https://git ...
- Qt动态库静态库的创建、使用、多级库依赖、动态库改成静态库等详细说明
本文描述的是windows系统下,通过qtcreator在pro文件中添加动态库与静态库的方法: 1.添加动态库(直接添加动态库文件.dll,非子项目) 通过qtcreator创建动态库的方法就不在此 ...