#include <bits/stdc++.h>
#define ll long long
#define INF 0x7f7f7f7f
using namespace std;
typedef pair<ll,int> PII;
const int N=1e5+10;
int n,m,ecnt;
int f[N][30];
int d[N],head[N];
int A[N];
ll sum[N];
struct edge {
int u,v,w,next;
} E[N<<1];
void add(int u,int v,int w) {
E[++ecnt].u=u;
E[ecnt].v=v;
E[ecnt].w=w;
E[ecnt].next=head[u];
head[u]=ecnt;
}
void dfs(int u,int fa) {
d[u]=d[fa]+1;
f[u][0]=fa;
for(int i=1; i<=20; i++)
f[u][i]=f[f[u][i-1]][i-1];
for(int i=head[u]; i; i=E[i].next) {
int v=E[i].v;
if(fa!=v) {
sum[v]=sum[u]+E[i].w;
dfs(v,u);
}
}
}
int LCA(int x,int y) {
if(d[x]<d[y])swap(x,y);
for(int i=20; i>=0; i--) {
if(d[f[x][i]]>=d[y])x=f[x][i];
}
if(x==y)return x;
for(int i=20; i>=0; i--) {
if(f[x][i]!=f[y][i]) {
x=f[x][i];
y=f[y][i];
}
}
return f[x][0];
}
ll path_dis(int x,int y) {
if(x==0||y==0)return 0;
return sum[x]+sum[y]-2*sum[LCA(x,y)];
}
int main() {
cin>>n>>m;
for(int i=1; i<n; i++) {
int u,v,w;
cin>>u>>v>>w;
add(u,v,w);
add(v,u,w);
}
dfs(1,0);
ll ans=0;
for(int i=1; i<=m; i++) {
cin>>A[i];
ans+=path_dis(A[i],A[i-1]);
}
//减去前一段,前去后一段,加上新的一段
for(int i=1; i<=m; i++) {
cout<<ans-path_dis(A[i],A[i-1])-path_dis(A[i],A[i+1])+path_dis(A[i-1],A[i+1])<<" ";
}
return 0;
}
景区导游(树上两点间距离(LCA不同写法))
于 2023-04-17 17:37:03 首次发布