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 }