求树上两点之间路径上最小边权
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 5e5+5;
int n, q, root;
int head[N], nxt[N << 1], to[N << 1], cccnnnttt, val[N << 1];
int fa[N][20], dep[N], minw[N][20];
void add(int u, int v, int w){
to[++cccnnnttt] = v;
val[cccnnnttt] = w;
nxt[cccnnnttt] = head[u];
head[u] = cccnnnttt;
}
void dfs(int u, int f){
fa[u][0] = f;
for (int i = 1;i <= 18;i++){
fa[u][i] = fa[fa[u][i - 1]][i - 1];
minw[u][i] = min(minw[u][i - 1], minw[fa[u][i - 1]][i - 1]);
}
for (int i = head[u];i;i = nxt[i]){
int v = to[i], w = val[i];
if (v == f) continue;
dep[v] = dep[u] + 1;
minw[v][0] = w;
dfs(v, u);
}
}
int LCA(int u, int v){
if (dep[u] < dep[v]) swap(u, v);
int res = INT_MAX;
for (int i = 18;i >= 0;i--){
if (dep[fa[u][i]] >= dep[v]){
u = fa[u][i];
res = min(res, minw[u][i]);
}
}
if (u == v) return res;
for (int i = 18;i >= 0;i--){
if (fa[u][i] != fa[v][i]){
u = fa[u][i];
v = fa[v][i];
res = min(res, min(minw[u][i], minw[v][i]));
}
}
res = min(res, min(minw[u][0], minw[v][0]));
return res;
}
int main(){
//ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
//memset(minw, 0x3f3f3f3f, sizeof minw);
cin >> n >> q ;
for (int i = 1;i < n;i++){
int u, v, w;
cin >> u >> v >> w;
add(u, v, w);
add(v, u, w);
}
dep[1] = 1;
dfs(1, 0);
while (q--){
int x, y;
cin >> x >> y;
cout << LCA(x, y) << '\n';
}
return 0;
}