LCA - 求任意两点间的距离
For each test case,in the first line there are two numbers
n(2<=n<=40000) and m (1<=m<=200),the number of houses and
the number of queries. The following n-1 lines each consisting three
numbers i,j,k, separated bu a single space, meaning that there is a road
connecting house i and house j,with length k(0<k<=40000).The
houses are labeled from 1 to n.
Next m lines each has distinct integers i and j, you areato answer the distance between house i and house j.OutputFor each test case,output m lines. Each line represents the answer of the query. Output a bland line after each test case.Sample Input
2
3 2
1 2 10
3 1 15
1 2
2 3 2 2
1 2 100
1 2
2 1
Sample Output
10
25
100
100 题目分析 : 给出一些点之间的长度,再给出一些询问,查任意两点间的距离。
思路分析 : 倍增LCA裸题
代码示例 :
#define ll long long
const int maxn = 4e4+5;
const double pi = acos(-1.0);
const int inf = 0x3f3f3f3f; int n, m, N;
struct node
{
int to, cost;
node(int _to = 0, int _cost = 0):to(_to),cost(_cost){}
};
vector<node>ve[maxn];
int dep[maxn];
int grand[maxn][30], gw[maxn][30]; void dfs(int x, int fa){
for(int i = 1; i <= N; i++){
grand[x][i] = grand[grand[x][i-1]][i-1];
gw[x][i] = gw[x][i-1] + gw[grand[x][i-1]][i-1];
}
for(int i = 0; i < ve[x].size(); i++){
int to = ve[x][i].to;
int cost = ve[x][i].cost; if (to == fa) continue;
dep[to] = dep[x] + 1;
grand[to][0] = x;
gw[to][0] = cost;
dfs(to, x);
}
} int lca(int a, int b){
// a 是在 b 的上面的
if (dep[a] > dep[b]) swap(a, b);
int ans = 0; for(int i = N; i >= 0; i--){
if (dep[a] < dep[b] && dep[grand[b][i]] >= dep[a]){
ans += gw[b][i];
b = grand[b][i];
}
}
// a, b 在同一层后
for(int i = N; i >= 0; i--){
if (grand[a][i] != grand[b][i]) {
ans += gw[a][i];
ans += gw[b][i];
a = grand[a][i], b = grand[b][i];
}
}
if (a != b) {
ans += gw[a][0];
ans += gw[b][0];
}
return ans;
} int main() {
//freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
int t;
int a, b, c; cin >> t;
while(t--){
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i++) ve[i].clear();
for(int i = 1; i < n; i++){
scanf("%d%d%d", &a, &b, &c);
ve[a].push_back(node(b, c));
ve[b].push_back(node(a, c));
}
memset(grand, 0, sizeof(grand));
memset(gw, 0, sizeof(gw));
dep[1] = 0;
N = floor(log(n)/log(2)); // 求出最大的2^k = N中的 k
dfs(1, 1);
for(int i = 1; i <= m; i++){
scanf("%d%d", &a, &b);
printf("%d\n", lca(a, b));
}
}
return 0;
} /*
5
8 100
1 2 1
2 4 1
2 5 1
2 6 1
1 3 1
3 7 1
1 8 1
*/
LCA - 求任意两点间的距离的更多相关文章
- AOJ GRL_1_C: All Pairs Shortest Path (Floyd-Warshall算法求任意两点间的最短路径)(Bellman-Ford算法判断负圈)
题目链接:http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_1_C All Pairs Shortest Path Input ...
- HDU2586(LCA应用:在带权树中求任意两点之间的距离)
How far away ? Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)To ...
- AOJ -0189 Convenient Location && poj 2139 Six Degrees of Cowvin Bacon (floyed求任意两点间的最短路)
http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=78207 看懂题就好. 求某一办公室到其他办公室的最短距离. 多组输入,n表示 ...
- Floyed-Warshall算法(求任意两点间最短距离)
思路:感觉有点像暴力啊,反正我是觉得很暴力,比如求d[i][j],用这个方法求的话,就直接考虑会不会经过点k(k是任意一点) ,最终求得最小值 看代码 #include<iostream> ...
- 计算GPS两点间的距离[单位为:米]
/** * 计算GPS两点间的距离[单位为:米] * @param center GPS当前数据(LonLat对象表示,LonLat.lon表示经度,LonLat.lat表示纬度) ...
- 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 ...
- 图算法之Floyd-Warshall 算法-- 任意两点间最小距离
1.Floyd-Warshall 算法 给定一张图,在o(n3)时间内求出任意两点间的最小距离,并可以在求解过程中保存路径 2.Floyd-Warshall 算法概念 这是一个动态规划的算法. 将顶点 ...
- HDOJ2001计算两点间的距离
计算两点间的距离 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Su ...
- HDOJ/HDU 2547 无剑无我(两点间的距离)
Problem Description 北宋末年,奸臣当道,宦官掌权,外侮日亟,辽军再犯.时下战火连连,烽烟四起,哀鸿遍野,民不聊生,又有众多能人异士群起而反,天下志士云集响应,景粮影从. 值此危急存 ...
随机推荐
- Intellij Idea更换主题
<h1 class="title">Intellij Idea更换主题</h1> <!-- 作者区域 --> <div class=&qu ...
- linux设备编号的内部表示
在内核中, dev_t 类型(在 <linux/types.h>中定义)用来持有设备编号 -- 主次部分都包 括. 对于 2.6.0 内核, dev_t 是 32 位的量, 12 位用作主 ...
- UVa1601 - The Morning after Halloween [单向bfs]
解题思路: 1.注意到2*2方格中必有一个#,那么最多只有192条通道,可以将所有非‘#’的位置提取出来用邻接表的方式建图,通过bfs搜索目标位置. 2.将三个ghost的位置(a,b,c)作为状态量 ...
- P1082 数列分段
题目描述 对于给定的一个长度为 \(N\) 的正整数数列 \(A_i\) ,现要将其分成连续的若干段,并且每段和不超过 \(M\) (可以等于 \(M\) ),问最少能将其分成多少段使得满足要求. 输 ...
- 基于Springboot+Junit+Mockito做单元测试
前言 前面的两篇文章讨论过< 为什么要写单元测试,何时写,写多细 >和<单元测试规范>,这篇文章介绍如何使用Springboot+Junit+Mockito做单元测试,案例选取 ...
- C# 标准性能测试高级用法
本文告诉大家如何在项目使用性能测试测试自己写的方法 在 C# 标准性能测试 已经告诉大家如何使用 BenchmarkDotNet 测试性能,本文会告诉大家高级的用法. 建议是创建一个控制台项目用来做性 ...
- gradle 打包后第三方登录不上
使用 gradlew clean assembleReleaseChannels 生成不用的渠道包后 第三方登录不上 原因:打包未设置好APP的 .keystore
- 微信小程序获取多个input和textarea的值(es6加微信小程序APi)
wxml js 俩行即可解决,money1,money2,money3
- hadoop中 namenode的持久化
一.为什么namenode持久化 namenode通过内存存储hdfs集群的元数据(目录结构 文件信息 块对应关系),如果内存出现问题,那么会数据丢失,需要通过持久化,把内存中的数据定期的存储在硬盘中 ...
- 【软件】Gimp内容识别填充开启工具1.0
*源文件起初存于Gimp-Registry,后因服务器维护成本问题,Gimp将原服务器中所有文件迁移至GimpGithub *博主只是将原插件中的内容识别填充功能进行打包处理,方便大家一键启用. 下载 ...