How far away ?
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
水题。
#include<bits/stdc++.h>
using namespace std;
const int maxn=40010;
int cnt=0,n;
int vis[maxn]; //访问标记
int fat[maxn]; //存父亲结点
int tar[maxn]; //存最近公共祖先结点
int dis[maxn]; //到树顶点的距离
typedef struct node
{
int v,w;
}node;
node e[maxn<<1];
vector<int>head[maxn<<1];
typedef struct que
{
int u,v,ans;
}que;
que d[maxn<<1];
vector<int>query[maxn<<1];
void init()
{
cnt=0;
for(int i=0;i<(maxn<<1);i++) head[i].clear();
for(int i=0;i<(maxn<<1);i++) query[i].clear();
for(int i=0;i<maxn;i++) fat[i]=i;
memset(vis,0,sizeof(vis));
memset(tar,0,sizeof(tar));
memset(dis,0,sizeof(dis));
}
void add(int a,int b,int c)
{
e[cnt].v=b;
e[cnt].w=c;
head[a].push_back(cnt++);
e[cnt].v=a;
e[cnt].w=c;
head[b].push_back(cnt++);
}
int fd(int x)
{
int r=x;
while(fat[r]!=r)
r=fat[r];
int i=x,j;
while(i!=r)
{
j=fat[i];
fat[i]=r;
i=j;
}
return r;
}
void join(int u,int v)
{
int fu=fd(u),fv=fd(v);
if(fu!=fv)
fat[fu]=fv;
}
void dfs_tree(int s)
{
vis[s]=1;
for(int i=0;i<head[s].size();i++)
{
if(!vis[e[head[s][i]].v])
{
dis[e[head[s][i]].v]=dis[s]+e[head[s][i]].w;
dfs_tree(e[head[s][i]].v);
join(e[head[s][i]].v,s);
tar[e[head[s][i]].v]=1;
}
}
for(int i=0;i<query[s].size();i++)
{
if(tar[d[query[s][i]].v])
{
d[query[s][i]].ans=fd(d[query[s][i]].v);
if(query[s][i]%2==0)
d[query[s][i]+1].ans=d[query[s][i]].ans;
else
d[query[s][i]-1].ans=d[query[s][i]].ans;
}
}
}
void dfs()
{
for(int i=1;i<=n;i++)
{
if(!vis[i])
{
dfs_tree(i);
}
}
}
int main()
{
int t,m;
int x,y,z;
scanf("%d",&t);
while(t--)
{
init();
scanf("%d%d",&n,&m);
for(int i=0; i<n-1; i++)
{
scanf("%d%d%d",&x,&y,&z);
add(x,y,z);
}
int a,b;
int num=0;
for(int i=0;i<m;i++)
{
scanf("%d%d",&a,&b);
d[num].u=a,d[num].v=b;
query[a].push_back(num++);
d[num].u=b,d[num].v=a;
query[b].push_back(num++);
}
dfs();
for(int i=0;i<num;i++)
{
if(i%2==0)
{
int k=dis[d[i].u] + dis[d[i].v] - 2*dis[d[i].ans];
printf("%d\n",k);
}
}
}
return 0;
}