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;
}

最新文章

  1. mysql qps tps计算
  2. 使用response实现文件的下载
  3. yum源的更新问题
  4. JAVA 根据用户输入数据求某年到某年有多少天
  5. nginx 编译模块说明
  6. Spring框架中的IOC和DI的区别
  7. TCP的滑动窗口机制【转】
  8. 使用Intellij Idea自定义MVC框架
  9. 【linux】安装samba服务
  10. 一大波jQuery事件即将来袭!
  11. Codeforces 862A Mahmoud and Ehab and the MEX
  12. callback理解
  13. 用同一台PC的两个网口实现Iperf的server端和client端
  14. ThinkPHP页面跳转success与error方法
  15. Mingw下载
  16. 八、自定义starter
  17. rtrim
  18. 配置MySQL GTID(Global Transaction IDs)复制
  19. C语言一些基础知识
  20. Linux引导启动程序 - boot

热门文章

  1. vue2-vux-fitness-project
  2. 1-1.go开发工具安装
  3. HDU_1005:Number Sequence
  4. MaxCompute 图计算用户手册(上)
  5. 【NS2】NS2中802.11代码深入理解—packet传输的流程(转载)
  6. TreeSet的运用之使用内部比较器实现自定义有序(重要)
  7. qt painter多个点的曲线
  8. POLARDB v2.0 技术解读
  9. oracle函数 mod(x,y)
  10. Linux下的一些配置