HDU 2586 How far away ?
Posted 自为
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 2586 How far away ?相关的知识,希望对你有一定的参考价值。
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 18652 Accepted Submission(s):
7268
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.
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问题
我们用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("%d\\n",g[x]+g[y]-2*g[LCA(x,y)]); 80 } 81 } 82 83 return 0; 84 }
以上是关于HDU 2586 How far away ?的主要内容,如果未能解决你的问题,请参考以下文章
hdu 2586 How far away?(树链剖分+前缀和)