HDU 2586 How far away ?

时间:2022-05-08
本文章向大家介绍HDU 2586 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

Source

ECJTU 2009 Spring Contest

Recommend

lcy   |   We have carefully selected several similar problems for you:  3486 2874 2888 3234 2818

带权的LCA问题

我们用g[i]表示i号节点走到根的权值

那么两个点之间的路径权值为,g[x]+g[y]-2*g[LCA(x,y)]

大概是这个样子

被圆圈出来的是需要减去的

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 const int MAXN=1e5+10;
 6 inline int read()
 7 {
 8     char c=getchar();int x=0,f=1;
 9     while(c<'0'||c>'9')    {if(c=='-')    f=-1;c=getchar();}
10     while(c>='0'&&c<='9')    x=x*10+c-48,c=getchar();return x*f;
11 }
12 int n,m,S=1; 
13 int f[MAXN][21],deep[MAXN],g[MAXN];
14 struct node
15 {
16     int u,v,w,nxt;
17 }edge[MAXN];
18 int head[MAXN];
19 int num=1;
20 inline void add_edge(int x,int y,int z)
21 {
22     edge[num].u=x;
23     edge[num].v=y;
24     edge[num].w=z;
25     edge[num].nxt=head[x];
26     head[x]=num++;
27 }
28 void dfs(int now)
29 {
30     for(int i=head[now];i!=-1;i=edge[i].nxt)
31         if(deep[edge[i].v]==0)
32         {
33             deep[edge[i].v]=deep[now]+1;
34             f[edge[i].v][0]=now;
35             g[edge[i].v]=g[now]+edge[i].w;
36             dfs(edge[i].v);
37         }
38             
39 }
40 inline void pre()
41 {
42     for(int i=1;i<=19;i++)
43         for(int j=1;j<=n;j++)
44             f[j][i]=f[f[j][i-1]][i-1];
45 }
46 inline int LCA(int x,int y)
47 {
48     if(deep[x]<deep[y])    swap(x,y);
49     for(int i=19;i>=0;i--)
50         if(deep[f[x][i]]>=deep[y])
51             x=f[x][i];
52     if(x==y)    return x;
53 
54     for(int i=19;i>=0;i--)
55         if(f[x][i]!=f[y][i])
56             x=f[x][i],y=f[y][i];
57     return f[x][0];
58 }
59 int main()
60 {
61     int T=read();
62     while(T--)
63     {
64         n=read();m=read();
65         memset(head,-1,sizeof(head));num=1;
66         memset(f,0,sizeof(f));
67         memset(deep,0,sizeof(deep));
68         for(int i=1;i<=n-1;i++)
69         {
70             int x=read(),y=read(),z=read();
71             add_edge(x,y,z);
72             add_edge(y,x,z);
73         }
74         deep[S]=1;
75         dfs(S);pre();
76         while(m--)
77         {
78             int x=read(),y=read();
79             printf("%dn",g[x]+g[y]-2*g[LCA(x,y)]);
80         }    
81     }
82     
83     return 0;
84 }