用数组记录每个定点的父亲,和到父亲的边的权值,利用在线的lca求解即可
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #define MAX 40007 using namespace std; typedef long long LL; struct { int v , next , w; }e[MAX<<1]; int head[MAX]; int cc = 0; int n,m; void add ( int u , int v , int w ) { e[cc].v = v; e[cc].w = w; e[cc].next = head[u]; head[u] = cc++; } int fa[MAX]; int dep[MAX]; int weight[MAX]; int depth; void build ( int u , int p ) { fa[u] = p; dep[u] = ++depth; for ( int i = head[u] ; i != -1 ; i =e[i].next ) { int v = e[i].v; if ( v == p ) continue; weight[v] = e[i].w; build ( v , u ); } } LL lca ( int u , int v ) { LL res = 0; while ( u!=v ) { if ( dep[v] > dep[u] ) res += weight[v] , v = fa[v]; if ( dep[u] > dep[v] ) res += weight[u] , u = fa[u]; if ( dep[u] == dep[v] && u != v ) res += weight[u]+weight[v] , v = fa[v] , u = fa[u]; } return res; } int main ( ) { int t,u,v,w; scanf ( "%d" , &t ); while ( t-- ) { depth = 0; cc = 0; memset ( head , -1 , sizeof ( head ) ); scanf ( "%d%d" , &n , &m ); for ( int i = 1 ; i < n ; i++ ) { scanf ( "%d%d%d" , &u , &v , &w ); add ( u , v , w ); add ( v , u , w ); } build ( 1 , -1 ); for ( int i = 0 ; i < m ; i++ ) { scanf ( "%d%d" , &u , &v ); printf ( "%lld\n" , lca ( u , v ) ); } } }