http://acm.hdu.edu.cn/showproblem.php?pid=2586 #include<iostream> using namespace std; #define N 40001 #define M 201 struct edge{ int next,v,w; edge(){}; edge(int a,int b,int c){ next=a;v=b;w=c; } }E[N*2]; struct query{ int next,v; query(){}; query(int a,int b){ next=a;v=b; } }Q[2*M]; int NE,NQ; int head_edge[N],head_query[N]; int bin[N],dis[N]; bool h[N]; int root[M]; void init(int n){ for(int i=1;i<=n;i++) bin[i]=i; NE=NQ=0; memset(dis,0,sizeof(dis)); memset(head_edge,-1,sizeof(head_edge)); memset(head_query,-1,sizeof(head_query)); } void insert_edge(int u,int v,int w){ E[NE]=edge(head_edge[u],v,w); head_edge[u]=NE++; } void insert_query(int u,int v){ Q[NQ]=query(head_query[u],v); head_query[u]=NQ++; } int find(int x){ if(bin[x]==x) return bin[x]; int r=find(bin[x]); dis[x]+=dis[bin[x]]; return bin[x]=r; } void merge(int x,int y,int k){ int fx=find(x); int fy=find(y); bin[fy]=fx; dis[fy]=dis[x]+k-dis[y]; } void LCA_Tarjan(int u){ h[u]=true; for(int i=head_edge[u];i!=-1;i=E[i].next){ int v=E[i].v; if(h[v]) continue; LCA_Tarjan(v); merge(u,v,E[i].w); } for(int i=head_query[u];i!=-1;i=Q[i].next){ int v=Q[i].v; if(h[v]) root[i>>1]=find(v); } } int main(void){ int t; scanf("%d",&t); int u[M],v[M]; while(t--){ int n,m,i; scanf("%d%d",&n,&m); init(n); for(i=0;i<n-1;i++){ int u,v,w; scanf("%d%d%d",&u,&v,&w); insert_edge(u,v,w); insert_edge(v,u,w); } for(i=0;i<m;i++){ scanf("%d%d",&u[i],&v[i]); insert_query(u[i],v[i]); insert_query(v[i],u[i]); } memset(root,-1,sizeof(root)); memset(h,0,sizeof(h)); for(i=1;i<=n;i++) if(!h[i]) LCA_Tarjan(i); for(i=0;i<m;i++){ int r=root[i]; find(u[i]); find(v[i]); find(r); int ans=dis[u[i]]+dis[v[i]]-2*dis[r]; printf("%d/n",ans); } } } LCA_Tarjan模板~