How far away ? HDU - 2586

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.

InputFirst 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(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
题解:倍增法(创造算法的人真的是牛),首先对于任意顶点,利用父亲节点的信息,可以通过Fa2[v]=Fa[Fa[v]]得到向上走两步所到的顶点。
再利用这一信息,又可以通过Fa4[v]=Fa2[Fa2[v]]得到其向上走四步所到的顶点。依次类推,可以得到其向上走 2的k次方 布所到顶点Fa[k][v].
 1 // ConsoleApplication1.cpp: 定义控制台应用程序的入口点。
 2 //
 3 
 4 //#include "stdafx.h"
 5 #include<cstdio>
 6 #include<vector>
 7 #include<cstring>
 8 #include<iostream>
 9 #include<algorithm>
10 using namespace std;
11 
12 const int max_log = 20;
13 const int maxn = 40004;
14 
15 int n, m, tot;
16 int head[maxn], dp[maxn], Fa[max_log][maxn], sum[maxn];
17 
18 struct node {
19     int to, va, next;
20 }e[2*maxn];
21 
22 void Inite() {
23     tot = 0;
24     memset(sum, 0, sizeof(sum));
25     memset(head, -1, sizeof(head));
26 }
27 
28 void addedge(int u, int v, int w) {
29     e[tot].to = v;
30     e[tot].va = w;
31     e[tot].next = head[u];
32     head[u] = tot++;
33 }
34 
35 void DFS(int u, int d, int pa) {
36     dp[u] = d;
37     Fa[0][u] = pa;
38     for (int i = head[u]; i != -1; i = e[i].next) {
39         int v = e[i].to;
40         if (v == pa) continue;
41         sum[v] = sum[u] + e[i].va;
42         DFS(v, d + 1, u);
43     }
44 }
45 
46 void Get_Fa() {
47     DFS(1, 0, -1);
48     for (int i = 0; i + 1 < max_log; i++) {
49         for (int v = 1; v <= n; v++) {
50             if (Fa[i][v] < 0) Fa[i + 1][v] = -1;
51             else Fa[i + 1][v] = Fa[i][Fa[i][v]];
52         }
53     }
54 }
55 
56 int Lca(int u, int v) {
57     if (dp[u] > dp[v]) swap(u, v);
58     for (int i = 0; i < max_log; i++) {
59         if ((dp[v] - dp[u]) >> i & 1) v = Fa[i][v];
60     }
61     if (u == v) return u;
62     for (int i = max_log; i >= 0; i--) {
63         if (Fa[i][u] != Fa[i][v]) {
64             u = Fa[i][u];
65             v = Fa[i][v];
66         }
67     }
68     return Fa[0][u];
69 }
70 
71 int main()
72 {
73     int kase;
74     cin >> kase;
75     while (kase--) {
76         Inite();
77         cin >> n >> m;
78         for (int i = 2; i <= n; i++) {
79             int u, v, w;
80             cin >> u >> v >> w;
81             addedge(u, v, w);
82             addedge(v, u, w);
83         }
84         Get_Fa();
85         for (int i = 1; i <= m; i++) {
86             int u, v;
87             cin >> u >> v;
88             int com_pa= Lca(u, v);
89             int ans = sum[u] - sum[com_pa] + sum[v] - sum[com_pa];
90             cout << ans << endl;
91         }
92     }
93     return 0;
94 }

 

posted @ 2017-11-28 00:03  天之道,利而不害  阅读(128)  评论(0)    收藏  举报