hdu 2586(裸LCA)
题意:
某村庄有n个小屋,n-1条道路连接着n个小屋(无环),求村庄A到村庄B的距离,要求是经过任一村庄不超过一次。
题解:
求出 lca = LCA(u,v) , 然后答案便是dist[u] + dist[v] - 2 * dist[lca];
AC代码:
1 #include<iostream> 2 #include<vector> 3 #include<cstdio> 4 #include<cmath> 5 #include<cstring> 6 using namespace std; 7 #define pb(x) push_back(x) 8 #define mem(a,b) memset(a,b,sizeof(a)) 9 const int maxn=4e4+50; 10 11 int n,q; 12 int dist[maxn];//dist[i]: 节点i与节点1的距离,假定1为根节点 13 int vs[2*maxn];//欧拉序列 14 int depth[2*maxn];//深度序列 15 int pos[maxn];//pos[i]:节点i在欧拉序列中第一次出现的位置 16 bool vis[maxn]; 17 struct Edge 18 { 19 int to; 20 int w; 21 Edge(int a=0,int b=0):to(a),w(b){} 22 }; 23 vector<Edge >G[maxn]; 24 void addEdge(int u,int v,int w) 25 { 26 G[u].pb(Edge(v,w)); 27 } 28 struct RMQ 29 { 30 int dp[31][2*maxn]; 31 void rmq() 32 { 33 int tot=2*n-1; 34 for(int i=1;i <= tot;++i) 35 dp[0][i]=i; 36 for(int k=1;(1<<k) <= tot;++k) 37 for(int i=1;((1<<k)+i-1) <= tot;++i) 38 if(depth[dp[k-1][i]] > depth[dp[k-1][i+(1<<(k-1))]]) 39 dp[k][i]=dp[k-1][i+(1<<(k-1))]; 40 else 41 dp[k][i]=dp[k-1][i]; 42 } 43 int lca(int u,int v) 44 { 45 u=pos[u],v=pos[v]; 46 if(u > v) 47 swap(u,v); 48 int k=log(v-u+1)/log(2); 49 return vs[min(dp[k][u],dp[k][v-(1<<k)+1])]; 50 } 51 }_rmq; 52 void Dfs(int u,int dis,int dep,int &k) 53 { 54 vs[++k]=u; 55 depth[k]=dep; 56 pos[u]=k; 57 dist[u]=dis; 58 vis[u]=true; 59 for(int i=0;i < G[u].size();++i) 60 { 61 int to=G[u][i].to; 62 int w=G[u][i].w; 63 if(!vis[to]) 64 { 65 Dfs(to,dis+w,dep+1,k); 66 vs[++k]=u; 67 depth[k]=dep; 68 } 69 } 70 } 71 void LCA() 72 { 73 int k=0; 74 Dfs(1,0,0,k); 75 _rmq.rmq(); 76 } 77 void Init() 78 { 79 mem(vis,false); 80 for(int i=1;i <= n;++i) 81 G[i].clear(); 82 } 83 int main() 84 { 85 // freopen("C:/Users/hyacinthLJP/Desktop/stdin/hdu2586.txt","r",stdin); 86 int t; 87 scanf("%d",&t); 88 while(t--) 89 { 90 Init(); 91 scanf("%d%d",&n,&q); 92 for(int i=1;i < n;++i) 93 { 94 int u,v,w; 95 scanf("%d%d%d",&u,&v,&w); 96 addEdge(u,v,w); 97 addEdge(v,u,w); 98 } 99 LCA(); 100 for(int i=1;i <= q;++i) 101 { 102 int u,v; 103 scanf("%d%d",&u,&v); 104 int lca=_rmq.lca(u,v); 105 printf("%d\n",dist[u]+dist[v]-2*dist[lca]); 106 } 107 } 108 return 0; 109 }