HDU2586 How far away ? (树链剖分求LCA)

用树链剖分求LCA的模板;

 1 #include<iostream>
 2 #include<algorithm>
 3 using namespace std;
 4 const int maxn=40005;
 5 int n,m;
 6 int head[maxn],to[maxn<<1],w[maxn<<1],nxt[maxn<<1],tot;
 7 int fa[maxn],dep[maxn],son[maxn],top[maxn],size[maxn],dis[maxn];
 8 
 9 void add(int x,int y,int z){
10     nxt[++tot]=head[x];
11     head[x]=tot;
12     to[tot]=y;
13     w[tot]=z;
14 }
15 
16 void dfs1(int u,int f){
17     fa[u]=f,size[u]=1,dep[u]=dep[f]+1;
18     for(int i=head[u];i;i=nxt[i]){
19         int v=to[i];
20         if(v==f) continue;
21         dis[v]=dis[u]+w[i];
22         dfs1(v,u);
23         size[u]+=size[v];
24         if(size[v]>size[son[u]]) son[u]=v;
25     }
26 }
27 
28 void dfs2(int u){
29     if(u==son[fa[u]]) top[u]=top[fa[u]];
30     else top[u]=u;//求top数组 
31     for(int i=head[u];i;i=nxt[i]){
32         int v=to[i];
33         if(v!=fa[u]) dfs2(v);
34     }
35 }
36 
37 int LCA(int u,int v){
38     while(top[u]!=top[v]){
39         if(dep[top[u]]>dep[top[v]]) u=fa[top[u]];
40         else v=fa[top[v]];
41     }
42     return dep[u]>dep[v]?v:u;
43 }
44 
45 int main(){
46     int T;
47     scanf("%d",&T);
48     while(T--){
49         scanf("%d%d",&n,&m);
50         for(int i=1;i<=n;i++) head[i]=dep[i]=dis[i]=son[i]=0;
51         tot=0;
52         for(int i=1;i<n;i++){
53             int x,y,z;
54             scanf("%d%d%d",&x,&y,&z);
55             add(x,y,z);add(y,x,z);
56         }
57         dfs1(1,0);
58         dfs2(1);
59         for(int i=1;i<=m;i++){
60             int x,y;
61             scanf("%d%d",&x,&y);
62             int k=LCA(x,y);
63             printf("%d\n",dis[x]+dis[y]-2*dis[k]);
64         }
65     }
66     return 0;
67 }

 

posted @ 2022-07-01 18:32  YHXo  阅读(16)  评论(0编辑  收藏  举报