HDU 2586 How Far Away? LCA水题
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
题意:给出一棵树,m个询问
每次询问给出a,b
问a,b的距离。
siz[i] 表示i到根节点的距离
思路:先求出lca=LCA(a,b)
则距离 = siz[a]+siz[b]-2*siz[lca]
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 5 using namespace std; 6 7 const int maxn=40000+5; 8 9 struct Edge 10 { 11 int to,next,w; 12 }edge[maxn<<1]; 13 int head[maxn]; 14 int tot; 15 int p[maxn][24]; 16 int siz[maxn]; 17 int dep[maxn]; 18 19 void init(int n) 20 { 21 tot=1; 22 memset(head,-1,sizeof(head)); 23 memset(siz,0,sizeof(siz)); 24 memset(dep,0,sizeof(dep)); 25 26 for(int i=1;i<=n;i++) 27 for(int j=0;j<24;j++) 28 p[i][j]=-1; 29 } 30 31 void addedge(int u,int v,int w) 32 { 33 edge[tot].to=v; 34 edge[tot].w=w; 35 edge[tot].next=head[u]; 36 head[u]=tot++; 37 } 38 39 void dfs(int n,int u,int fa) 40 { 41 for(int i=head[u];~i;i=edge[i].next) 42 { 43 int v=edge[i].to; 44 int w=edge[i].w; 45 if(!dep[v]&&v!=fa) 46 { 47 dep[v]=dep[u]+1; 48 p[v][0]=u; 49 siz[v]=siz[u]+w; 50 dfs(n,v,u); 51 } 52 } 53 } 54 55 void init_lca(int n) 56 { 57 for(int j=1;(1<<j)<=n;j++) 58 { 59 for(int i=1;i<=n;i++) 60 { 61 if(p[i][j-1]!=-1) 62 { 63 p[i][j]=p[p[i][j-1]][j-1]; 64 } 65 } 66 } 67 } 68 69 int solve(int n,int u,int v) 70 { 71 if(u==v) 72 return 0; 73 if(dep[u]<dep[v]) 74 { 75 swap(u,v); 76 } 77 78 int init_u=u; 79 int init_v=v; 80 81 int cnt; 82 for(cnt=0;(1<<cnt)<=dep[u];cnt++) 83 ; 84 cnt--; 85 86 for(int j=cnt;j>=0;j--) 87 { 88 if(dep[u]-(1<<j)>=dep[v]) 89 u=p[u][j]; 90 } 91 92 if(u==v) 93 return (siz[init_u]-siz[u]); 94 95 for(int j=cnt;j>=0;j--) 96 { 97 if(p[u][j]!=-1&&p[u][j]!=p[v][j]) 98 { 99 u=p[u][j]; 100 v=p[v][j]; 101 } 102 } 103 int lca=p[u][0]; 104 105 return (siz[init_u]+siz[init_v]-2*siz[lca]); 106 107 } 108 109 int main() 110 { 111 int test; 112 scanf("%d",&test); 113 114 while(test--) 115 { 116 int n,m; 117 scanf("%d%d",&n,&m); 118 119 init(n); 120 121 for(int i=1;i<n;i++) 122 { 123 int u,v,w; 124 scanf("%d%d%d",&u,&v,&w); 125 addedge(u,v,w); 126 addedge(v,u,w); 127 } 128 129 dfs(n,1,-1); 130 init_lca(n); 131 132 /* 133 for(int i=1;i<=n;i++) 134 printf("%d\n",siz[i]); 135 */ 136 137 for(int i=1;i<=m;i++) 138 { 139 int u,v; 140 scanf("%d%d",&u,&v); 141 //printf("eee\n"); 142 printf("%d\n",solve(n,u,v)); 143 } 144 } 145 146 return 0; 147 }