[CodeVS2370] 小机房的树 (LCA)

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 }

  

时间: 2024-11-19 16:46:15

[CodeVS2370] 小机房的树 (LCA)的相关文章

小机房的树——LCA 启蒙题

大概从一个月前的学考准备阶段就没好好干过什么事,五月底六月初因为要突击文科而削减了奥赛,班主任也说中午暂时别去机房.然后高考放假在家里准备炎德(间断地打了十五盘Dota 2,十五盘是凤凰,输了三盘),本来带了几本文科的资料但是没动.高考完了我们会学校学考.学考完那天下午只有一堂英语,于是我就一个人待在机房,考完回寝室听人说班主任中午说晚上要考试.然后就考试,用十三号和十四号两天的晚自习考了高考卷子(湖南的全国卷乙).成绩是语文一百,数学九十一,英语一百三十五(其实当时因为时间关系而没有做听力,我

codevs 2370 小机房的树(LCA)

过了这么长的时间终于开始看LCA了... 有一次训练题卡在LCA当时不会...拖了好久好久...其实现在还是不会... 只会tarjan... 传送门 板子题咯 tarjan的算法就是基于先序遍历的顺序的 #include <bits/stdc++.h> using namespace std; inline int read() { int x = 0, f = 1; char ch = getchar(); while (ch < '0' || ch > '9') { if (

LCA(倍增在线算法) codevs 2370 小机房的树

codevs 2370 小机房的树 时间限制: 1 s 空间限制: 256000 KB 题目等级 : 钻石 Diamond 题目描述 Description 小机房有棵焕狗种的树,树上有N个节点,节点标号为0到N-1,有两只虫子名叫飘狗和大吉狗,分居在两个不同的节点上.有一天,他们想爬到一个节点上去搞基,但是作为两只虫子,他们不想花费太多精力.已知从某个节点爬到其父亲节点要花费 c 的能量(从父亲节点爬到此节点也相同),他们想找出一条花费精力最短的路,以使得搞基的时候精力旺盛,他们找到你要你设计

codevs 2370 小机房的树

2370 小机房的树 时间限制: 1 s 空间限制: 256000 KB 题目等级 : 钻石 Diamond 题目描述 Description 小机房有棵焕狗种的树,树上有N个节点,节点标号为0到N-1,有两只虫子名叫飘狗和大吉狗,分居在两个不同的节点上.有一天,他们想爬到一个节点上去搞基,但是作为两只虫子,他们不想花费太多精力.已知从某个节点爬到其父亲节点要花费 c 的能量(从父亲节点爬到此节点也相同),他们想找出一条花费精力最短的路,以使得搞基的时候精力旺盛,他们找到你要你设计一个程序来找到

小机房的树 codevs 2370

2370 小机房的树 时间限制: 1 s 空间限制: 256000 KB 题目等级 : 钻石 Diamond 题解 查看运行结果 题目描述 Description 小机房有棵焕狗种的树,树上有N个节点,节点标号为0到N-1,有两只虫子名叫飘狗和大吉狗,分居在两个不同的节点上.有一天,他们想爬到一个节点上去搞基,但是作为两只虫子,他们不想花费太多精力.已知从某个节点爬到其父亲节点要花费 c 的能量(从父亲节点爬到此节点也相同),他们想找出一条花费精力最短的路,以使得搞基的时候精力旺盛,他们找到你要

【codevs2370】小机房的树

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

小机房的树(codevs 2370)

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

小机房的树CODEVS 2370

————最近公共祖先和动态规划的完美结合 [题目描述] 小机房有棵焕狗种的树,树上有N个节点,节点标号为0到N-1,有两只虫子名叫飘狗和大吉狗,分居在两个不同的节点上.有一天,他们想爬到一个节点上去搞基,但是作为两只虫子,他们不想花费太多精力.已知从某个节点爬到其父亲节点要花费 c 的能量(从父亲节点爬到此节点也相同),他们想找出一条花费精力最短的路,以使得搞基的时候精力旺盛,他们找到你要你设计一个程序来找到这条路,要求你告诉他们最少需要花费多少精力. [输入描述] 第一行一个n,接下来n-1行

【codevs】2370 小机房的树

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