Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 13390 Accepted Submission(s): 5018

Problem Description

There are n houses in the village and some bidirectional roads connecting them. Every day peole always like to ask like this “How far is it if I want to go from house A to house B”? Usually it hard to answer. But luckily int this village the answer is always unique, since the roads are built in the way that there is a unique simple path(“simple” means you can’t visit a place twice) between every two houses. Yout task is to answer all these curious people.

Input

First line is a single integer T(T<=10), indicating the number of test cases.

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(0k<=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.

Output

For 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

【题解】



设p[i][j]表示i往上走2^j个节点到达的节点。

p[i][j]=p[p[i][j-1]][j-1];

然后先让所求的两个点的高度一样。

即高度高的一直往上走走到和高度底的高度一样;

然后再一起往上走走到共同的祖先;(最近);

找到祖先后输出dis[x]+dis[y]-2*dis[LCA];就是距离了。

这个距离是树上的最短距离。还是很有用的。可以扩展下;

#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm> using namespace std; const int MAXN = 50000;
const int MAX = 16; vector <int> son[MAXN],w[MAXN];
int n,p[MAXN][MAX+5],dep[MAXN],pre[MAX+5],m;
long long dis[MAXN]; void input(int &r)
{
char t = getchar();
while (!isdigit(t)) t = getchar();
r = 0;
while (isdigit(t)) r = r * 10 + t - '0', t = getchar();
} void dfs(int x,int f)
{
dep[x] = dep[f] + 1;
p[x][0] = f;
for (int i = 1; i <= MAX; i++)
p[x][i] = p[p[x][i - 1]][i - 1];
int len = son[x].size();
for (int i = 0; i <= len - 1; i++)
{
int y = son[x][i];
if (y != f)
{
dis[y] = dis[x] + w[x][i];
dfs(y, x);
}
}
} int main()
{
//freopen("F:\\rush.txt", "r", stdin);
pre[0] = 1;
for (int i = 1; i <= MAX; i++)
pre[i] = pre[i - 1] << 1;
int T;
input(T);
while (T--)
{
input(n); input(m);
for (int i = 1; i <= n; i++)
son[i].clear(),w[i].clear();
for (int i = 1; i <= n - 1; i++)
{
int x, y, z;
input(x); input(y); input(z);
son[x].push_back(y);
w[x].push_back(z);
son[y].push_back(x);
w[y].push_back(z);
}
dis[1] = 0;
dfs(1, 0);
for (int i = 1; i <= m; i++)
{
int t0, t1,pret0,pret1;
input(t0); input(t1);
pret0 = t0; pret1 = t1;
if (dep[t0] > dep[t1])
swap(t0, t1);
for (int i = MAX; i >= 0; i--)
if (dep[t0] <= dep[t1] - pre[i])
t1 = p[t1][i];
if (t1 == t0)
{
printf("%I64d\n",dis[pret0]+dis[pret1]-2*dis[t0]);
continue;
}
for (int i = MAX; i >= 0; i--)
{
if (p[t0][i] == p[t1][i])
continue;
t0 = p[t0][i], t1 = p[t1][i];
}
printf("%I64d\n", dis[pret0]+dis[pret1]-2*dis[p[t0][0]]);
}
}
return 0;
}

【37.48%】【hdu 2587】How far away ?(3篇文章,3种做法,LCA之树上倍增)的更多相关文章

  1. 【37.48%】【hdu 2587】How far away ?(3篇文章,3种做法,LCA之ST算法(RMQ))

    Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s) ...

  2. 【37.48%】【hdu 2587】How far away ?(3篇文章,3种做法,LCA之Tarjan算法)

    Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s) ...

  3. HDU 1248 寒冰王座 (水题的N种做法!)(含完全背包)

    寒冰王座 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  4. HDU 4822 Tri-war(LCA树上倍增)(2013 Asia Regional Changchun)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4822 Problem Description Three countries, Red, Yellow ...

  5. Hdu1874 畅通工程续 2017-04-12 18:37 48人阅读 评论(0) 收藏

    畅通工程续 Time Limit : 3000/1000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other) Total Submiss ...

  6. HDU 2587 - 很O_O的汉诺塔

    看题传送门 吐槽题目 叫什么很O_O的汉诺塔我还@.@呢. 本来是想过一段时间在来写题解的,不过有人找我要. 本来排名是第8的.然后搞了半天,弄到了第五.不过代码最短~ 截止目前就9个ID过,小小的成 ...

  7. 48. 二叉树两结点的最低共同父结点(3种变种情况)[Get lowest common ancestor of binary tree]

    [题目] 输入二叉树中的两个结点,输出这两个结点在数中最低的共同父结点. 二叉树的结点定义如下:  C++ Code  123456   struct BinaryTreeNode {     int ...

  8. hdu 5748(求解最长上升子序列的两种O(nlogn)姿势)

    Bellovin Time Limit: / MS (Java/Others) Memory Limit: / K (Java/Others) Total Submission(s): Accepte ...

  9. HDU 1251 统计难题(字典树 裸题 链表做法)

    Problem Description Ignatius最近遇到一个难题,老师交给他很多单词(只有小写字母组成,不会有重复的单词出现),现在老师要他统计出以某个字符串为前缀的单词数量(单词本身也是自己 ...

随机推荐

  1. Mongodb停止和启动

    mongodb开启.停止.重启操作 #开启service mongodb start#停止service mongodb stop#重启service mongodb restart

  2. vuxdemo1

    //main.js import Vue from 'vue' import router from './router' import store from './store' import axi ...

  3. PHPCMS快速建站系列之邮箱验证

    1. 登录163邮箱,->设置,开启POP3服务->把SMTP服务器地址复制到PHPCMS后台. 2.开启客户端授权密码 3.填写相关信息,.可以在测试邮箱填入邮箱地址测试

  4. 【JZOJ4835】【GDOI2017模拟10.31】量化交易

    题目描述 数据范围 解法 贪心: 从左往右枚举,设枚举到元素为x,并维护一个堆: 设此时堆顶元素为y, 如果x大于y,那么x可以与y产生差价,立即将差价贡献给答案. 如果y之前已经和其他元素z产生过差 ...

  5. HZOJ trade

    强烈谴责$skyh$的没$\Huge 脸$行为. 很经典的可反悔贪心,然而我一直以为是sbdp还一直想着怎么优化…… 正常的贪心肯定是不对的. 但是由于A-C=A-B+B-C, 所以用一个小根堆维护, ...

  6. 巨蟒python全栈开发-第11阶段 ansible_project6

    今日大纲: 1.计划任务前端页面 2.计划任务新增实现 3.计划任务编辑 4.项目详情 5.文件上传 6.replace模块介绍 1.计划任务前端页面 2.计划任务新增实现 3.计划任务编辑 4.项目 ...

  7. LightOJ 1370 Bi-shoe and Phi-shoe【欧拉函数 && 质数】

    题目链接: http://lightoj.com/login_main.php?url=volume_showproblem.php?problem=1370 题意: 给定值,求满足欧拉值大于等于这个 ...

  8. mysql 中合并查询结果union用法 or、in与union all 的查询效率

    mysql 中合并查询结果union用法 or.in与union all 的查询效率 (2016-05-09 11:18:23) 转载▼ 标签: mysql union or in 分类: mysql ...

  9. 重磅开源|AOP for Flutter开发利器——AspectD

    https://github.com/alibaba-flutter/aspectd 问题背景 随着Flutter这一框架的快速发展,有越来越多的业务开始使用Flutter来重构或新建其产品.但在我们 ...

  10. hdu 4629 Burning (扫描线)

    Problem - 4629 以前写过PSLG模拟的版本,今天写了一下扫描线做这题. 其实这题可以用set存线段来做,类似于判断直线交的做法.不过实现起来有点麻烦,于是我就直接暴力求交点了. 代码如下 ...