模板倍增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 ...
随机推荐
- 【SqlServer】SqlServer的常规操作
创建一张新表,不负责任何数据(该表不会有原来表的主键.索引等等) select * into NewTable from OldTable where 1<>1; 创建一张新表,并且复制旧 ...
- Wifiner for Mac(WiFi 状况分析工具)破解版安装
1.软件简介 Wifiner 是 macOS 系统上一款 Wifi 分析工具,仅需几次点击即可对您的 Wi-Fi 网络连接进行分析和故障排除.扫描您的 Wi-Fi 网络,获取包含交互式彩色编码热 ...
- android异步向服务器请求数据
下面就android向服务器请求数据的问题分析如下: 1.在android4.0以后的版本,主线程(UI线程)不在支持网络请求,原因大概是影响主线程,速度太慢,容易卡机,所以需要开启新的线程请求数据: ...
- Chrome F12 温故而知新 :因为重定向导致清空Network信息
虽然我以前都是用Fiddler 4来作为解决方案.但实际上可以勾选 [Preserve log]来保存日志 这样就不担心因为页面重定向导致清空了日志了
- Android studio ButterKnife插件
1.功能:给所有的有id的控件添加注解 2.github地址 https://github.com/avast/android-butterknife-zelezny 3.插件下载地址 http:// ...
- python3版本中的zip函数
例如,有两个列表: 1 2 >>>a = [1,2,3] >>>b = [4,5,6] 使用zip()函数来可以把列表合并,并创建一个元组对的列表. 1 2 > ...
- 20款有用的JavaScript和CSS库
Web开发与设计已经发展达到了新的高峰.创建一个网站并不是那么简单了,因为它使用的是几年前.今天是时间创造有吸引力的网站,不仅吸引了游客的关注也让他们订婚.另外,和功能的有吸引力的功能添加到该网站不应 ...
- 【转】WPF自定义控件与样式(9)-树控件TreeView与菜单Menu-ContextMenu
一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等. 本文主要内容: 菜单Menu的自定义样式: 右键菜单ContextMenu的自定义样式 ...
- [hive] hive 安装、配置
一.hive安装 1.官网下载 1.2.2版本 http://apache.fayea.com/hive/hive-1.2.2/ 2. 解压,此处目录为 /opt/hadoop/hive-1.2.2 ...
- Markdown 表格
表格的基本写法很简单,就跟表格的形状很相似,冒号在左边表示左对齐,右边表示右对齐,两边都有表示居中,如果都不写冒号则默认左对齐 学号|姓名|分数 :-|:-:|-: 小明|男|75 小红|女|79 小 ...