How far away ?
Time Limit: 2000 /1000 MS (Java/Others) Memory Limit: 32768 /32768 K (Java/Others)
Total Submission(s): 14859 Accepted Submission(s): 5647
Problem Description
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 算出最近公共祖先t ,长度就是dis [u] +dis [v] -2 *dis [t] .
LCA-ST
```
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<ctime>
#include<string>
#include<stack>
#include<deque>
#include<queue>
#include<list>
#include<set>
#include<map>
#include<cstdio>
#include<limits.h>
#define MOD 1000000007
#define fir first
#define sec second
#define fin freopen("/home/ostreambaba/文档/input.txt", "r", stdin)
#define fout freopen("/home/ostreambaba/文档/output.txt", "w", stdout)
#define mes(x, m) memset(x, m, sizeof(x))
#define Pii pair<int, int>
#define Pll pair<ll, ll>
#define INF 1e9+7
#define inf 0x3f3f3f3f
#define Pi 4.0*atan(1.0)
#define lowbit(x) (x&(-x))
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
typedef long long ll;
typedef unsigned long long ull;
const double eps = 1e-9 ;
const int maxn = 4 *1e4 +10 ;
using namespace std ;
inline int read(){
int x=0 ,f=1 ;
char ch=getchar();
while (ch<'0' ||ch>'9' ){if (ch=='-' )f=-1 ;ch=getchar();}
while (ch>='0' &&ch<='9' )x=x*10 +ch-'0' ,ch=getchar();
return x*f;
}
int dp[20 ][maxn<<1 ],to;
int tot,ver[maxn<<1 ],head[maxn],first[maxn],dep[maxn<<1 ],dir[maxn],vis[maxn];
struct edge{
int v,w,next;
}g[maxn<<1 ];
void init(){
tot=0 ;
to=0 ;
mes(head,-1 );
mes(vis,false );
}
inline void addEdge(int u,int v,int w){
g[to].v=v;
g[to].w=w;
g[to].next=head[u];
head[u]=to++;
}
void dfs(int u,int dt){
vis[u]=true ;
ver[++tot]=u;
first[u]=tot;
dep[tot]=dt;
for (int i=head[u];~i;i=g[i].next){
if (!vis[g[i].v]){
int v=g[i].v,w=g[i].w;
dir[v]=dir[u]+w;
dfs(v,dt+1 );
ver[++tot]=u;
dep[tot]=dt;
}
}
}
void rmq(int N,int limits){
for (int i=1 ;i<=N;++i){
dp[0 ][i]=i;
}
for (int i=1 ;i<=limits;++i){
for (int j=1 ;j<=N;++j){
if (j+(1 <<i)-1 <=N){
int a=dp[i-1 ][j],b=dp[i-1 ][j+(1 <<i>>1 )];
dp[i][j]=(dep[a]<dep[b]?a:b);
}
}
}
}
inline int query(int l,int r){
int k=floor (log2(r-l+1 ));
int a=dp[k][l],b=dp[k][r-(1 <<k)+1 ];
return dep[a]<dep[b]?a:b;
}
int LCA(int u,int v){
int x=first[u],y=first[v];
if (x>y){
swap(x,y);
}
int res=query(x,y);
return ver[res];
}
int main(){
int t=read();
while (t--){
init();
int n,m;
n=read(),m=read();
for (int i=0 ;i<n-1 ;++i){
int u,v,w;
u=read(),v=read(),w=read();
addEdge(u,v,w);
addEdge(v,u,w);
}
dfs(1 ,1 );
dir[1 ]=0 ;
rmq(2 *n-1 ,(log2(2 *n-1 )+1 ));
while (m--){
int u,v;
u=read(),v=read();
int t=LCA(u,v);
printf ("%d\n" ,dir[u]+dir[v]-dir[t]*2 );
}
}
return 0 ;
}
typedef long long ll;
typedef unsigned long long ull;
const double eps = 1 e-9 ;
const int maxn = 4 *1e4 +10 ;
const int maxm = 205 ;
using namespace std;
inline int read (){
int x =0 ,f=1 ;
char ch=getchar();
while (ch<'0' ||ch>'9' ){if (ch=='-' )f=-1 ;ch=getchar();}
while (ch>='0' &&ch<='9' )x =x *10 +ch-'0' ,ch=getchar();
return x *f ;
}
struct edge{
int u,v,w,next ;
};
struct qedge{
int u,v,idx,next ;
};
edge g[maxn<<1 ];
qedge q[maxm<<1] ;
int p[maxn],tot,to,head[maxn],qhead[maxn],vis[maxn],dis[maxn],lca[maxm<<1 ];
void init(){
tot=to=0 ;
mes(head,-1 );
mes(vis,false);
mes(qhead,-1 );
}
inline void addEdge(int u,int v,int w){
g[tot].v=v;
g[tot].w=w;
g[tot].next =head[u];
head[u]=tot++;
}
inline void addQEdge(int u,int v,int w){
q[to] .u=u;
q[to] .v=v;
q[to] .idx=w;
q[to] .next =qhead[u];
qhead[u]=to++;
}
inline int find(int x ){
return x ==p[x ]?x :p[x ]=find(p[x ]);
}
inline void merge(int x ,int y ){
x =find(x ),y =find(y );
if (x !=y ){
p[y ]=x ;
}
}
void tarjan(int u){
vis[u]=true;
for (int i=head[u];~i;i=g[i].next ){
int v=g[i].v,w=g[i].w;
if (!vis[v]){
dis[v]=dis[u]+w;
tarjan(v);
p[v]=u;
}
}
for (int i=qhead[u];~i;i=q[i] .next ){ // 写成head[u],尴尬一直wa
int v=q[i] .v;
if (vis[v]){
lca[q[i] .idx]=find(v);
}
}
}
int main(){
//freopen ("/home/ostreambaba/文档/input.txt" , "r" , stdin);
//freopen ("/home/ostreambaba/文档/output.txt" , "w" , stdout);
int t=read ();
while (t--){
init();
int n,m ;
int u,v,w;
tot=0 ;
n=read (),m =read ();
for (int i=1 ;i<=n;++i){
p[i]=i;
}
for (int i=0 ;i<n-1 ;++i){
scanf("%d %d %d " ,&u,&v,&w);
addEdge(u,v,w);
addEdge(v,u,w);
}
to=0 ;
for (int i=1 ;i<=m ;++i){
scanf("%d %d " ,&u,&v);
addQEdge(u,v,i);
addQEdge(v,u,i);
}
dis[1 ]=0 ;
tarjan(1 );
for (int i=0 ;i<to;i+=2 ){
printf ("%d \n" ,dis[q[i] .u]+dis[q[i] .v]-2 *dis [lca[q[i] .idx]]);
//cout <<q[i] .u<<" " <<q[i] .v<<" " <<lca[q[i] .idx]<<endl;
}
}
return 0 ;
}