How far away ?

题目链接:https://acm.hdu.edu.cn/showproblem.php?pid=2586

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 int t;
 6 int n, m;
 7 const int maxn= 40005;
 8 struct edge{
 9     int to, next, wt;
10 }e[maxn<<1];
11 int head[maxn], tot;
12 void add(int u, int v, int w){
13     e[++tot].to=v;
14     e[tot].next=head[u];
15     e[tot].wt=w;
16     head[u]=tot;
17 }
18 int lg[maxn+10];
19 void lg2(){//构造lg2函数实现功能lg2() 
20     lg[0]=-1;
21     for(int i=1; i<=maxn; i++)lg[i]=lg[i/2]+1;
22 }
23 int depth[maxn],  fa[maxn][20], dis[maxn];
24 void inif(){//初始化所有数组 
25     memset(e, 0, sizeof(e));
26     memset(head, 0, sizeof(head));
27     memset(depth, 0, sizeof(depth));
28     memset(fa, 0, sizeof(fa));
29     memset(dis, 0, sizeof(dis));
30 }
31 void dfs(int u){
32     for(int i=head[u]; i; i=e[i].next){
33         int v=e[i].to;//与u相连接的点 
34         if(v == fa[u][0])//判断是否已经访问过 
35             continue;
36         depth[v]=depth[u]+1;//深度计算 
37         dis[v]=dis[u]+e[i].wt;//求到根距离 
38         fa[v][0]=u;//fa[v][0]表示v节点走2^0后的节点 
39         dfs(v);
40     }
41 }
42 void st_create(){//构造st表 
43     for(int j=1; j<=lg[maxn]; j++)
44         for(int i=1; i<=n; i++)
45             fa[i][j]=fa[fa[i][j-1]][j-1];
46 } 
47 int lca(int x, int y){
48     if(depth[x] < depth[y])swap(x, y);
49     while(depth[x] > depth[y])
50         x=fa[x][lg[depth[x]-depth[y]]];
51     if(x == y)
52         return x;
53     for(int i=lg[n]; i>=0; i--)
54         if(fa[x][i] != fa[y][i])
55             x=fa[x][i], y=fa[y][i];
56     return fa[x][0];
57 }
58 int main()
59 {
60     scanf("%d",&t);
61     lg2();
62     while(t--){
63         inif();//初始化数组 
64         scanf("%d%d", &n, &m);
65         for(int i=1; i<n; i++){
66             int a, b, c;
67             scanf("%d%d%d", &a, &b, &c);
68             add(a, b, c); add(b, a, c);
69         }
70         dfs(1);//计算每个节点的深度、到根的距离以及fa数组的初始化 
71         st_create();
72         while(m--){
73             int l, r;
74             scanf("%d%d", &l, &r);
75             int lr=lca(l, r);
76             printf("%d\n", dis[l]+dis[r]-2*dis[lr]);
77         }
78     }
79     return 0;
80 }

 

posted @ 2022-04-20 15:35  TFLSNOI  阅读(78)  评论(0编辑  收藏  举报