HDU2586.How far away ?-LCA(在线ST算法)

How far away ?

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


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
 
 
代码:
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cmath>
 5 using namespace std;
 6 const int N=40000+10;
 7 const int M=25;
 8 int dp[2*N][M];
 9 bool vis[N];
10 struct edge{
11     int u,v,w,next;
12 }e[2*N];
13 int tot,head[N];
14 inline void add(int u,int v,int w,int &k){
15     e[k].u=u;e[k].v=v;e[k].w=w;
16     e[k].next=head[u];head[u]=k++;
17     u=u^v;v=u^v;u=u^v;
18     e[k].u=u;e[k].v=v;e[k].w=w;
19     e[k].next=head[u];head[u]=k++;
20 }
21 int ver[2*N],R[2*N],first[N],dir[N];
22 void dfs(int u,int dep){
23     vis[u]=true;ver[++tot]=u;first[u]=tot;R[tot]=dep;
24     for(int k=head[u];k!=-1;k=e[k].next)
25     if(!vis[e[k].v]){
26         int v=e[k].v,w=e[k].w;
27         dir[v]=dir[u]+w;
28         dfs(v,dep+1);
29         ver[++tot]=u;R[tot]=dep;
30     }
31 }
32 void ST(int n){
33     for(int i=1;i<=n;i++)
34         dp[i][0]=i;
35     for(int j=1;(1<<j)<=n;j++){
36         for(int i=1;i+(1<<j)-1<=n;i++){
37             int a=dp[i][j-1],b=dp[i+(1<<(j-1))][j-1];
38             dp[i][j]=R[a]<R[b]?a:b;
39         }
40     }
41 }
42 int RMQ(int l,int r){
43     int k=0;
44     while((1<<(k+1))<=r-l+1)k++;
45     int a=dp[l][k],b=dp[r-(1<<k)+1][k];
46     return R[a]<R[b]?a:b;
47 }
48 int LCA(int u,int v){
49     int x=first[u],y=first[v];
50     if(x>y)swap(x,y);
51     int res=RMQ(x,y);
52     return ver[res];
53 }
54 int main(){
55     int cas;
56     scanf("%d",&cas);
57     while(cas--){
58         int n,q,num=0;
59         scanf("%d%d",&n,&q);
60         memset(head,-1,sizeof(head));
61         memset(vis,false,sizeof(vis));
62         for(int i=1;i<n;i++){
63             int u,v,w;
64             scanf("%d%d%d",&u,&v,&w);
65             add(u,v,w,num);
66         }
67         tot=0;dir[1]=0;
68         dfs(1,1);
69         ST(2*n-1);
70         while(q--){
71             int u,v;
72             scanf("%d%d",&u,&v);
73             int lca=LCA(u,v);
74             printf("%d\n",dir[u]+dir[v]-2*dir[lca]);
75         }
76     }
77     return 0;
78 }

猜你喜欢

转载自www.cnblogs.com/ZERO-/p/9114403.html