hdu 2586 How far away ?

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 17365    Accepted Submission(s): 6701


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
 
Source
 
Recommend
 
lca水题 
#include <cstring>
#include <ctype.h>
#include <cstdio>
#define N 60000

struct Edge
{
    int to,dis;
    Edge * next; 
}edge[N<<1],*head[N];
int T,n,m,cnt,dad[N][25],dep[N],dis[N];
inline void Read(int &x)
{
    register char ch=getchar();
    for(x=0;!isdigit(ch);ch=getchar());
    for(;isdigit(ch);x=x*10+ch-'0',ch=getchar());
}
inline void init()
{
    cnt=0;
    memset(head,0,sizeof(head));
    memset(dad,0,sizeof(dad));
    memset(dep,0,sizeof(dep));
}
inline void ins(int u,int v,int w)
{
    edge[++cnt].next=head[u];
    edge[cnt].to=v;
    edge[cnt].dis=w;
    head[u]=edge+cnt;
}
void dfs(int x)
{
    dep[x]=dep[dad[x][0]]+1;
    for(int i=0;dad[x][i];++i)
    dad[x][i+1]=dad[dad[x][i]][i];
    for(Edge * u=head[x];u;u=u->next)
    {
        int v=u->to;
        if(dad[x][0]!=v)
        {
            dad[v][0]=x;
            dis[v]=u->dis+dis[x];
            dfs(v);
        }
    }
}
void swap(int &m,int &n)
{
    int tmp=n;
    n=m;
    m=tmp;
}
int lca(int x,int y)
{
    if(dep[x]>dep[y]) swap(x,y);
    for(int i=20;i>=0;--i)
    if(dep[dad[y][i]]>=dep[x]) y=dad[y][i];
    if(x==y) return x;
    for(int i=20;i>=0;--i)
    if(dad[x][i]!=dad[y][i])
    x=dad[x][i],y=dad[y][i];
    return dad[x][0];
}
int main()
{
    Read(T);
    for(;T--;)
    {
        init();
        Read(n);Read(m);
        for(int x,y,z,i=1;i<n;++i)
        {
            Read(x);
            Read(y);
            Read(z);
            ins(x,y,z);
            ins(y,x,z);
        }
        dfs(1);
        for(int x,y;m--;)
        {
            Read(x);
            Read(y);
            int z=lca(x,y);
            printf("%d
",dis[x]+dis[y]-2*dis[z]);
        }
    }
    return 0;
}
我们都在命运之湖上荡舟划桨,波浪起伏着而我们无法逃脱孤航。但是假使我们迷失了方向,波浪将指引我们穿越另一天的曙光。
原文地址:https://www.cnblogs.com/ruojisun/p/7400067.html