码迷,mamicode.com
首页 > 其他好文 > 详细

[CodeVS2370] 小机房的树 (LCA)

时间:2016-04-11 00:08:05      阅读:182      评论:0      收藏:0      [点我收藏+]

标签:

Description

  小机房有棵焕狗种的树,树上有N个节点,节点标号为0到N-1,有两只虫子名叫飘狗和大吉狗,分居在两个不同的节点上。有一天,他们想爬到一个节点上去搞基,但是作为两只虫子,他们不想花费太多精力。
  已知从某个节点爬到其父亲节点要花费 c 的能量(从父亲节点爬到此节点也相同),他们想找出一条花费精力最短的路,以使得搞基的时候精力旺盛,他们找到你要你设计一个程序来找到这条路,要求你告诉他们最少需要花费多少精力

Input

  第一行一个n,接下来n-1行每一行有三个整数u,v, c 。表示节点 u 爬到节点 v 需要花费 c 的精力。
  第n+1行有一个整数m表示有m次询问。接下来m行每一行有两个整数 u ,v 表示两只虫子所在的节点

Output

  一共有m行,每一行一个整数,表示对于该次询问所得出的最短距离。

Sample Input

3
1 0 1
2 0 1
3
1 0
2 0
1 2

Sample Output

1
1
2

HINT

  1<=n<=50000, 1<=m<=75000, 0<=c<=1000

Source

Solution

  倍增LCA

技术分享
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 struct edge
 4 {
 5     int v, w, nxt;
 6 }e[100005];
 7 int fst[50005], q[50005], front, back;
 8 int fa[17][50005], dis[50005], dep[50005];
 9 
10 void addedge(int i, int u, int v, int w)
11 {
12     e[i] = (edge){v, w, fst[u]}, fst[u] = i;
13 }
14 
15 int LCA(int u, int v)
16 {
17     if(dep[u] > dep[v]) swap(u, v);
18     for(int i = 16; ~i; i--)
19         if(dep[fa[i][v]] >= dep[u])
20             v = fa[i][v];
21     if(u == v) return u;
22     for(int i = 16; ~i; i--)
23         if(fa[i][u] != fa[i][v])
24             u = fa[i][u], v = fa[i][v];
25     return fa[0][u];
26 }
27 
28 int main()
29 {
30     int n, m, u, v, w;
31     cin >> n;
32     for(int i = 1; i < n; i++)
33     {
34         cin >> u >> v >> w;
35         addedge(i << 1, ++u, ++v, w);
36         addedge(i << 1 | 1, v, u, w);
37     }
38     q[++back] = 1, dep[1] = fa[0][1] = 1;
39     while(front != back)
40     {
41         u = q[++front];
42         for(int i = fst[u]; i; i = e[i].nxt)
43             if(e[i].v != fa[0][u])
44             {
45                 q[++back] = e[i].v;
46                 dep[e[i].v] = dep[u] + 1;
47                 fa[0][e[i].v] = u;
48                 dis[e[i].v] = dis[u] + e[i].w;
49             }
50     }
51     for(int i = 1; i <= 16; i++)
52         for(int j = 1; j <= n; j++)
53             fa[i][j] = fa[i - 1][fa[i - 1][j]];
54     cin >> m;
55     while(m--)
56     {
57         cin >> u >> v, u++, v++;
58         cout << dis[u] + dis[v] - 2 * dis[LCA(u, v)] << endl;
59     }
60     return 0;
61 }
View Code

  

[CodeVS2370] 小机房的树 (LCA)

标签:

原文地址:http://www.cnblogs.com/CtrlCV/p/5376386.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!