HDU 2586 How far away ?

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<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
struct Edge
{
    int u,v,w;
    Edge(){}
    Edge(int _u,int _v,int _w):u(_u),v(_v),w(_w){}
};
const int N=4e4+5;
vector<Edge>G[N];
bool vis[N];
int f[N][32],d[N],dis[N],n,m;
void dfs(int u,int dep,int length)
{
    if(vis[u])return;
    d[u]=dep;
    dis[u]=length;
    vis[u]=1;
    int len=G[u].size();
    for(int i=0;i<len;i++)
    {
        Edge e=G[u][i];
        dfs(e.v,dep+1,length+e.w);
    }
}
void bz()
{
    for(int j=1;j<=30;j++)
        for(int i=1;i<=n;i++)
            f[i][j]=f[f[i][j-1]][j-1];
}
int query(int u,int v)
{
    int res=0;
    if(d[u]<d[v])swap(u,v);
    int dc=d[u]-d[v];
    for(int i=0;i<30;i++)
        if(dc&(1<<i))
           res+=dis[u]-dis[f[u][i]],u=f[u][i];
    if(u==v)return res;
    for(int i=30;i>=0;i--)
        if(f[u][i]!=f[v][i])
            res+=dis[u]-dis[f[u][i]]+dis[v]-dis[f[v][i]],u=f[u][i],v=f[v][i];
    return res+dis[u]-dis[f[u][0]]+dis[v]-dis[f[v][0]];
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)G[i].clear();
        memset(vis,0,sizeof(vis));
        for(int i=0;i<n-1;i++)
        {
            int u,v,w;
            scanf("%d%d%d",&u,&v,&w);
            G[u].push_back(Edge(u,v,w));
            G[v].push_back(Edge(v,u,w));
            f[v][0]=u;
        }
        dfs(1,0,0);
        bz();
        for(int i=0;i<m;i++)
        {
            int u,v;
            scanf("%d%d",&u,&v);
            printf("%d\n",query(u,v));
        }
    }
    return 0;
}

 

 

posted on 2016-07-29 09:59    阅读(126)  评论(0编辑  收藏  举报

导航