(important) 树中root到每一个node都存在唯一路径,
// dfs(root) dis[node]求出root到node节点的距离
//so len(u,v) = dis[u] + dis[v] - 2dis[LCA(u,v)]; //LCA比较简单不谈,但初始化要放在函数外,很奇怪,坑了我1h
//实锤水题垃圾
#include<iostream> #include<cstdio> #include<vector> #include<cstring> #include<string> using namespace std; const int maxn = 4e4 + 15; int n,m,sum;//n node,m query bool rudu[maxn]; typedef struct { int v,value; }edge; vector<edge> Grape[maxn]; int query[maxn][2];// 0 ~ u / 1 ~ v int arr[maxn];//每个查询的结果 bool vis[maxn]; int father[maxn]; int dis[maxn]; int find(int u) { if(u!=father[u]) father[u] = find(father[u]); return father[u]; } void Tarjan(int u) { for(int i=0;i!=Grape[u].size();++i) { int v = Grape[u][i].v;//相邻节点 Tarjan(v); father[v] = u; } vis[u] = true; for(int i=0;i!=m;++i) { int ans; if(u==query[i][0]&&vis[query[i][1]]) { ans = find(query[i][1]); arr[i] = ans; } if(u==query[i][1]&&vis[query[i][0]]) { ans = find(query[i][0]); arr[i] = ans; } } } //bool flag[maxn]; void dfs(int root) { //flag[root] = true; for(int i=0;i!=Grape[root].size();++i) { int v = Grape[root][i].v; sum += Grape[root][i].value; dis[v] = sum; dfs(v); sum -= Grape[root][i].value; } } int main() { int T,u,v; cin>>T; while(T--) { cin>>n>>m; for(int i=1;i<=n;++i) { father[i] = i; Grape[i].clear();//清空图 } memset(rudu,false,sizeof(rudu)); memset(query,0,sizeof(query)); memset(arr,0,sizeof(arr)); memset(vis,false,sizeof(vis)); edge node; for(int i=0;i!=n-1;++i) { cin>>u>>node.v>>node.value; rudu[node.v] = true; Grape[u].push_back(node); }//带权值的边 for(int i=0;i!=m;++i) { cin>>query[i][0]>>query[i][1]; } int root; for(int v=1;v<=n;++v) if(!rudu[v]) { root = v;//根节点 Tarjan(v); } //arr存储父节点 //dfs 根到图中各节点的距离 //for(int i=0;i!=m;++i) // cout<<arr[i]<<endl; sum = 0;//根到各个节点的距离 memset(dis,0,sizeof(dis)); // memset(flag,false,sizeof(flag)); dfs(root); //for(int i=1;i<=n;++i) // cout<<dis[v]<<endl; for(int i=0;i!=m;++i) { cout<<dis[query[i][0]]+dis[query[i][1]] - 2*dis[arr[i]]<<endl; } } }