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 = 1e-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;
}