最近公共祖先
dis[a,b] = dis[1,a]+dis[1,b]-2*dis[1,lca[a,b]];
#include<stdio.h> #include<algorithm> #include<string.h> #include<string> #include<vector> #include<queue> #include<iostream> #include<deque> using namespace std; #define inf 1000000000 #define MAXN 40010 struct edge { int fr,to,w,next; }edg[MAXN*2],edg1[MAXN]; int cnt,tot; int head[MAXN],head1[MAXN]; bool vis[MAXN]; void add(int u,int v,int w) { edg[cnt].fr=u; edg[cnt].to=v; edg[cnt].w=w; edg[cnt].next=head[u]; head[u]=cnt++; } void add1(int u,int v,int w) { edg1[tot].next=head1[u]; edg1[tot].to=v; edg1[tot].fr=u; edg1[tot].w=w; head1[u]=tot++; } int dis[MAXN],lca[MAXN],fa[MAXN]; int find1(int a) { if(a==fa[a]) return a; else { int b=find1(fa[a]); return fa[a]=b; } } void tarjan(int u) { // printf("1"); vis[u]=1; fa[u]=u; for(int i=head1[u];i!=-1;i=edg1[i].next) { int v=edg1[i].to; if(vis[v]) lca[edg1[i].w]=find1(v); } for(int i=head[u];i!=-1;i=edg[i].next) { int v=edg[i].to; if(!vis[v]) { dis[v]=dis[u]+edg[i].w; tarjan(v); fa[v]=u; } } } int main() { int t; scanf("%d",&t); while(t--) { int n,m; scanf("%d%d",&n,&m); memset(head,-1,sizeof(head)); cnt=0; for(int i=1;i<n;i++) { int u,v,w; scanf("%d%d%d",&u,&v,&w); add(u,v,w); add(v,u,w); } tot=0; memset(vis,0,sizeof(vis)); memset(head1,-1,sizeof(head1)); for(int i=1;i <= m;i++) //离线算法 记录下这2个点查询的排名 { int a,b; scanf("%d%d",&a,&b); add1(a,b,i); add1(b,a,i); } dis[1]=0; tarjan(1); for(int i=0;i<tot;i+=2) { int a,b,c; a=edg1[i].fr; b=edg1[i].to; c=edg1[i].w; printf("%d ",dis[a]+dis[b]-2*dis[lca[c]]); } //printf(" "); } return 0; }