模板倍增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 ...
随机推荐
- 6.翻译系列:EF 6 Code-First中数据库初始化策略(EF 6 Code-First系列)
原文链接:http://www.entityframeworktutorial.net/code-first/database-initialization-strategy-in-code-firs ...
- Chrome Debugger 温故而知新:上下文环境
最早是在IOS开发中看到过这种调试方式.在无意间发现Chrome Debugger也可以.直接上图: 解释:默认的控制台想访问变量.都是只能访问全局的.但当我们用debugger; 断点进入到内部时, ...
- Django TemplateDoesNotExist
在联系Django的时候,启动正常,我在浏览器上输入URL地址后报错 TemplateDoesNotExist at /test/ 解决方案 默认这里是空的,这里我们填上我们静态文件的地址
- lua -- 物品的配置文件,表的形式保存
do local goodsprop= { RECORDS={ []={ BuyGold= , RecoverPrice= , Value= , Param2= , UseTimesPerDay= , ...
- SAP BW 数据库表命名规则
SAP BW 数据库表命名规则 已有 315 次阅读2012/6/8 15:55 |系统分类:专业内容| SAP, 命名, 数据库表 Namings for Cube: /BI<C OR DIG ...
- Python多线程与多线程中join()的用法
多线程实例 https://www.cnblogs.com/cnkai/p/7504980.html 知识点一:当一个进程启动之后,会默认产生一个主线程,因为线程是程序执行流的最小单元,当设置多线程时 ...
- Angularjs中config中置入以下拦截器
$httpProvider.interceptors.push(['$rootScope', '$q', '$localStorage', function ($rootScope, $q, $loc ...
- 什么是位、字节、字、KB、MB (转)
回顾一下按位操作符和移位操作符的知识,顺便复习一下位相关的基础知识. 位:"位(bit)"是电子计算机中最小的数据单位.每一位的状态只能是0或1. 字节:8个二进制位构成1个&qu ...
- 织梦中在线显示pdf文件的方法
如何在织梦中添加pdf文件并显示呢?下面这个教程将带领大家来操作.(注:手机版无法查看) 第一步:在系统-系统基本参数-附件设置中添加pdf格式 并且将大小调大 第二步:在核心-内容模型-普通文章中添 ...
- 大杂烩 -- 四种生成和解析XML文档的方法详解
基础大杂烩 -- 目录 众所周知,现在解析XML的方法越来越多,但主流的方法也就四种,即:DOM.SAX.JDOM和DOM4J DOM:在现在的Java JDK里都自带了,在xml-apis.jar包 ...