倍增法求LCA

倍增法求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 }

猜你喜欢

转载自www.cnblogs.com/HNFOX/p/11273997.html
今日推荐