倍增法求LCA
可以利用LCA快速的求出树上两点间的最短路
时间复杂度O(nlogn)
1 #include<iostream>
2 #include<string.h>
3 #include<algorithm>
4 #include<vector>
5 #include<map>
6 #include<bitset>
7 #include<set>
8 #include<math.h>
9 #include<string>
10 #if !defined(_WIN32)
11 #include<bits/stdc++.h>
12 #endif // !defined(_WIN32)
13 #define ll long long
14 #define dd double
15 using namespace std;
16 struct edge
17 {
18 int to;
19 int weight;
20 int next;
21 }e[500005];
22 int head[100086];
23 int p[100086][25];
24 int deep[100086];
25 ll dis[100086];
26 int n, m;
27 int tot;
28 void add(int x, int y, int z)
29 {
30 tot++;
31 e[tot].to = y;
32 e[tot].weight = z;
33 e[tot].next = head[x];
34 head[x] = tot;
35 }
36 void dfs(int x, int f)
37 {
38 p[x][0] = f;
39 deep[x] = deep[f] + 1;
40 for (int i = 1; (1 << i) <= deep[x]; i++)
41 p[x][i] = p[p[x][i - 1]][i - 1];
42 for (int i = head[x]; i; i = e[i].next)
43 {
44 int to = e[i].to;
45 if (to != f)
46 {
47 dis[to] = dis[x] + e[i].weight;
48 dfs(to, x);
49 }
50 }
51 }
52 int lca(int x, int y)
53 {
54 if (deep[x] < deep[y])
55 swap(x, y);
56 while (deep[x] > deep[y])
57 x = p[x][(int)log2(deep[x] - deep[y])];
58 if (x == y)
59 return y;
60 for (int k = (int)log2(deep[x]); k >= 0; k--)
61 if (p[x][k] != p[y][k])
62 {
63 x = p[x][k];
64 y = p[y][k];
65 }
66 return p[x][0];
67 }
68 int main()
69 {
70 cin >> n >> m;
71 for (int i = 1; i < n; i++)
72 {
73 int x, y, z;
74 cin >> x >> y >> z;
75 add(x, y, z);
76 add(y, x, z);
77 }
78 dfs(1, 0);
79 for (int i = 1; i <= m; i++)
80 {
81 int x, y;
82 cin >> x >> y;
83 int c = lca(x, y);
84 cout << dis[x] + dis[y] - 2 * dis[c] << endl;
85 }
86 return 0;
87 }