[codevs2370]小机房的树
来源:互联网 发布:偷网站源码包方法 编辑:程序博客网 时间:2024/05/18 03:38
题目描述 Description
小机房有棵焕狗种的树,树上有N个节点,节点标号为0到N-1,有两只虫子名叫飘狗和大吉狗,分居在两个不同的节点上。有一天,他们想爬到一个节点上去搞基,但是作为两只虫子,他们不想花费太多精力。已知从某个节点爬到其父亲节点要花费 c 的能量(从父亲节点爬到此节点也相同),他们想找出一条花费精力最短的路,以使得搞基的时候精力旺盛,他们找到你要你设计一个程序来找到这条路,要求你告诉他们最少需要花费多少精力
输入描述 Input Description
第一行一个n,接下来n-1行每一行有三个整数u,v, c 。表示节点 u 爬到节点 v 需要花费 c 的精力。
第n+1行有一个整数m表示有m次询问。接下来m行每一行有两个整数 u ,v 表示两只虫子所在的节点
输出描述 Output Description
一共有m行,每一行一个整数,表示对于该次询问所得出的最短距离。
样例输入 Sample Input
3
1 0 1
2 0 1
3
1 0
2 0
1 2
样例输出 Sample Output
1
1
2
数据范围及提示 Data Size & Hint
1<=n<=50000, 1<=m<=75000, 0<=c<=1000
lca的板子题
对于节点i,rank[i]为i到根节点的距离
将0作为根节点
fa[i][j]表示i的第2的j次方个父亲
这样fa[i][log2(n)]实际是考虑了树为链的情况。
过程类似于二分
#include<iostream>#include<cstdio>#include<cmath>using namespace std;const int MAXN = 50000 + 5;struct edge{ int f,t,v;}l[MAXN << 1];int num,n,m,head[MAXN],next[MAXN << 1],rank[MAXN],fa[MAXN][25],deep[MAXN];void init(int n){ for(int i = 0;i <= n;i ++)//从0开始 { head[i] = -1; }}void build(int f,int t,int v){ l[++ num] = (edge){f,t,v}; next[num] = head[f]; head[f] = num;}void make_tree(int p,int f){ if(head[f] == -1)return; for(int i = head[f];i != -1;i = next[i]) { int v = l[i].t; if(v == p)continue; rank[v] = rank[f] + l[i].v; deep[v] = deep[f] + 1; fa[v][0] = f; make_tree(f,v); }}void make_lca(){ for(int j = 1;j <= log2(n);j ++) for(int i = 1;i <= n;i ++)fa[i][j] = fa[fa[i][j - 1]][j - 1];}int find_lca(int x,int y){ if(deep[x] < deep[y])swap(x,y); for(int i = log2(n);i >= 0;i --) { if(deep[fa[x][i]] >= deep[y])x = fa[x][i]; if(deep[x] == deep[y])break; } if(x == y)return x; for(int i = log2(n);i >= 0;i --) { if(fa[x][i] != fa[y][i]) { x = fa[x][i]; y = fa[y][i]; } } return fa[x][0];}int main(){ cin >> n; init(n); int x,y,z; for(int i = 1;i <= n - 1;i ++) { cin >> x >> y >> z; build(x,y,z); build(y,x,z); } make_tree(0,0); make_lca(); cin >> m; for(int i = 1;i <= m;i ++) { cin >> x >> y; cout << rank[x] + rank[y] - rank[find_lca(x,y)] * 2 << '\n'; } return 0;}
Tips:由于节点编号从零开始,初始化时记得head[0] = -1,避免在建树时死循环。
0 0
- Codevs2370 小机房的树
- codevs2370小机房的树
- 【codevs2370】小机房的树
- [codevs2370]小机房的树
- 【日常学习】【倍增LCA】codevs2370 小机房的树题解
- 【codevs2370】小机房的树,RMQ求LCA
- 倍增lca学习笔记(codevs2370小机房的树题解)
- 小机房的树
- 小机房的树
- 小机房的树
- 小机房的树
- 【codevs 2370】小机房的树
- Codevs_P2370 小机房的树(LCA)
- [LCA][CODEVS 2370]小机房的树
- Codevs 2370 小机房的树
- Codevs 2370 小机房的树
- 【codevs 2370】小机房的树
- 2370 小机房的树,lca
- Atitit 医学之道 attilax总结
- 快速排序
- 算法导论 练习题 6.1-6
- Java学习【知识点3】
- 2012年佛山市GDOI选拔赛题 加边
- [codevs2370]小机房的树
- javaSE学习06_if条件语句
- ArcGIS中的动态投影
- poj 1847 Tram dijktra
- 机器视觉学习笔记--图像滤波1
- how to assign more that 31 VFs to one VM
- 集合类3-Map
- 五、药店的药品销售统计系统(排序应用)
- redis-07-redis启动警告处理