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 }
原文地址:https://www.cnblogs.com/ZERO-/p/9114403.html