思路:
树上倍增模板题
#include<cstdio> #include<iostream> #include<vector> using namespace std; const int maxn = 10010; inline void qread(int &x){ x = 0; register int ch = getchar(); while(ch < '0' || ch > '9') ch = getchar(); while(ch >= '0' && ch <= '9'){ x = 10 * x + ch - 48; ch = getchar(); } } int n, m; vector<int> G[maxn]; vector<int> W[maxn]; int llog[maxn]; int deep[maxn]; int f[maxn][30]; int g[maxn]; inline void init(){ qread(n); qread(m); for(int i=1; i<n; ++i){ int x, y, z; qread(x), qread(y), qread(z); G[x].push_back(y); G[y].push_back(x); W[x].push_back(z); W[y].push_back(z); } deep[1] = 1; } void dfs(int x, int sum = 0){ g[x] = sum; for(int i=0; i<G[x].size(); ++i) if(!deep[G[x][i]]){ f[G[x][i]][0] = x; deep[G[x][i]] = deep[x] + 1; dfs(G[x][i], sum + W[x][i]); } } inline void STtree(){ for(int i=2; i<=n; ++i) llog[i] = llog[i >> 1] + 1; for(int j = 1; j <= llog[n]; ++j) for(int i=1; i<=n; ++i) f[i][j] = f[f[i][j-1]][j-1]; } inline int LCA(int x, int y){ if(x == y) return x; if(deep[x] < deep[y]) swap(x, y); for(int j = llog[n]; j>=0; --j) if(deep[f[x][j]] >= deep[y]) x = f[x][j]; if(x == y) return x; for(int j = llog[n]; j>=0; --j) if(f[x][j] != f[y][j]){ x = f[x][j]; y = f[y][j]; } return f[x][0]; } int main(void){ init(); dfs(1); STtree(); while(m--){ int x, y; qread(x), qread(y); printf("%d\n", g[x] + g[y] - (g[LCA(x, y)] << 1)); } }