There are n houses in the village and some bidirectional roads connecting them. Every day peole always like to ask like this "How far is it if I want to go from house A to house B"? Usually it hard to answer. But luckily int this village the answer is always unique, since the roads are built in the way that there is a unique simple path("simple" means you can't visit a place twice) between every two houses. Yout task is to answer all these curious people.
Input
First line is a single integer T(T<=10), indicating the number of test cases.
For each test case,in the first line there are two numbers n(2<=n<=40000) and m (1<=m<=200),the number of houses and the number of queries. The following n-1 lines each consisting three numbers i,j,k, separated bu a single space, meaning that there is a road connecting house i and house j,with length k(0<k<=40000).The houses are labeled from 1 to n.
Next m lines each has distinct integers i and j, you areato answer the distance between house i and house j.
Output
For each test case,output m lines. Each line represents the answer of the query. Output a bland line after each test case.
Sample Input
2 3 2 1 2 10 3 1 15 1 2 2 3 2 2 1 2 100 1 2 2 1
Sample Output
10 25 100 100
题解:裸的lca。。。。。。。。
萌新的第一道lca
#include<cstdio>
#include<cmath>
#include<string>
#include<cstring>
#include<map>
#include<queue>
#include<iostream>
#include<algorithm>
#include<set>
using namespace std;
const int maxn=100100;
int dp[maxn][30],ff[maxn],vs[maxn];
struct dd
{
int n,e,v;
};dd d[maxn];
int h[maxn],top,dk[maxn],f[maxn];
struct no{
int i,v;
bool operator <(const no &a)const{
return v>a.v;
}
};
void s0(int s,int e,int v){
d[top].e=e;
d[top].v=v;
d[top].n=h[s];
h[s]=top++;
}
priority_queue < no >q;
void gdk(int s){
dk[s]=0;
q.push((no){s,0});
while(!q.empty()){
no p=q.top();
q.pop();
if(f[p.i]==-1)f[p.i]=1;else continue;
for(int i=h[p.i];i!=-1;i=d[i].n){
int v=d[i].v,y=d[i].e;
if(dk[y]>dk[p.i]+v){
dk[y]=dk[p.i]+v;
q.push((no){y,dk[y]});
}
}
}
}
int top1,in[maxn];
void dfs(int fath,int i,int k){
vs[++top1]=i;
ff[top1]=k;
in[i]=top1;
for(int j=h[i];j!=-1;j=d[j].n){
if(fath==d[j].e)continue;
dfs(i,d[j].e,k+1);
vs[++top1]=i;
ff[top1]=k;
}
}
int gmi(int x,int y){
return ff[x]<ff[y]?x:y;
}
void st(int n)
{
for(int i=1; i<=n; i++)dp[i][0]=i;
for(int j=1; (1<<j)<=n; j++)
{
for(int i=1; i+(1<<j)-1<=n; i++)
{
dp[i][j]=gmi(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);
}
}
}
int rmq(int l,int r)
{
int k=0;
if(l>r)swap(l,r);
while((1<<(k+1))<=r-l+1)k++;
return gmi(dp[l][k],dp[r-(1<<k)+1][k]);
}
void init(int m){
memset(h,-1,sizeof(h));
memset(f,-1,sizeof(f));
top1=0,top=0;
for(int i=1;i<=m;i++)dk[i]=999999999;
}
int main()
{
int m,n;
int T;
scanf("%d",&T);
while(T--){
scanf("%d%d",&m,&n);
init(m);
int s,e,v;
for(int i=0;i<m-1;i++){
scanf("%d%d%d",&s,&e,&v);
s0(s,e,v);
s0(e,s,v);
}
gdk(1);
dfs(-1,1,0);
st(top1);
while(n--){
scanf("%d%d",&s,&e);
int fa=vs[rmq(in[s],in[e])];
printf("%d\n",dk[e]+dk[s]-2*dk[fa]);
}
}
return 0;
}