SPOJ QTREE2 (LCA - 倍增 在线)
You are given a tree (an undirected acyclic connected graph) with N nodes, and edges numbered 1, 2, 3...N-1. Each edge has an integer value assigned to it, representing its length.
We will ask you to perfrom some instructions of the following form:
- DIST a b : ask for the distance between node a and node b
or - KTH a b k : ask for the k-th node on the path from node a to node b
Example:
N = 6
1 2 1 // edge connects node 1 and node 2 has cost 1
2 4 1
2 5 2
1 3 1
3 6 2
Path from node 4 to node 6 is 4 -> 2 -> 1 -> 3 -> 6
DIST 4 6 : answer is 5 (1 + 1 + 1 + 2 = 5)
KTH 4 6 4 : answer is 3 (the 4-th node on the path from node 4 to node 6 is 3)
Input
The first line of input contains an integer t, the number of test cases (t <= 25). ttest cases follow.
For each test case:
- In the first line there is an integer N (N <= 10000)
- In the next N-1 lines, the i-th line describes the i-th edge: a line with three integers a b c denotes an edge between a, b of cost c (c <= 100000)
- The next lines contain instructions "DIST a b" or "KTH a b k"
- The end of each test case is signified by the string "DONE".
There is one blank line between successive tests.
Output
For each "DIST" or "KTH" operation, write one integer representing its result.
Print one blank line after each test.
Example
Input:
1 6
1 2 1
2 4 1
2 5 2
1 3 1
3 6 2
DIST 4 6
KTH 4 6 4
DONE Output:
5
3 思路:
倍增裸题。。。套板子,
求第k个的时候需要处理下,其他没什么。,。
实现代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int M = 2e5+;
int dist[M],p[M][],dep[M],head[M];
int cnt1,n; struct node{
int to,next,w;
}e[M]; void add(int u,int v,int w){
e[++cnt1].w=w;e[cnt1].to=v;e[cnt1].next=head[u];head[u]=cnt1;
e[++cnt1].w=w;e[cnt1].to=u;e[cnt1].next=head[v];head[v]=cnt1;
} void dfs(int u){
for(int i = head[u];i != -;i=e[i].next){
int v = e[i].to;
if(v == p[u][]) continue;
dep[v] = dep[u] + ;
dist[v] = dist[u] + e[i].w;
p[v][] = u; //p[i][0]存i的父节点
dfs(v);
}
} void init(){
for(int j = ;(<<j)<=n;j++){
for(int i = ;i <= n;i++){
p[i][j] = p[p[i][j-]][j-];
//cout<<i<<" "<<j<<" "<< p[i][j]<<endl;
}
}
} int lca(int a,int b){
if(dep[a] > dep[b]) swap(a,b);
int h = dep[b] - dep[a]; //h为高度差
for(int i = ;(<<i)<=h;i++){ //(1<<i)&f找到h化为2进制后1的位置,移动到相应的位置
if((<<i)&h) b = p[b][i];
//比如h = 5(101),先移动2^0祖先,然后再移动2^2祖先
}
//cout<<a<<" "<<b<<endl;
if(a!=b){
for(int i = ;i >= ;i --){
if(p[a][i]!=p[b][i]){ //从最大祖先开始,判断a,b祖先,是否相同
a = p[a][i]; b = p[b][i]; //如不相同,a,b,同时向上移动2^j
}
}
a = p[a][]; //这时a的father就是LCA
}
return a;
} int kth(int u,int k){
for(int i = ;i < ;i ++)
if(k >> i&)
u = p[u][i];
return u;
} int main()
{
int t,u,v,w,k;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
cnt1 = ;
//init();
memset(head,-,sizeof(head));
for(int i = ;i < n-;i ++){
scanf("%d%d%d",&u,&v,&w);
add(u,v,w);
}
dfs();
init();
char s[];
while(scanf("%s",s)!=EOF){
if(s[]=='O') break;
scanf("%d%d",&u,&v);
int num = lca(u,v);
if(s[]=='I'){
printf("%d\n",dist[u]+dist[v]-*dist[num]);
}
if(s[]=='T'){
scanf("%d",&k);
int x = dep[u] - dep[num];
if(x + >= k)
printf("%d\n",kth(u,k-));
else printf("%d\n",kth(v,dep[v]+dep[u]-*dep[num]+-k));
}
}
}
return ;
}
SPOJ QTREE2 (LCA - 倍增 在线)的更多相关文章
- LCA(倍增在线算法) codevs 2370 小机房的树
codevs 2370 小机房的树 时间限制: 1 s 空间限制: 256000 KB 题目等级 : 钻石 Diamond 题目描述 Description 小机房有棵焕狗种的树,树上有N个节点, ...
- SPOJ DISQUERY LCA + 倍增
裸题,如此之水- Code: #include<cstdio> #include<algorithm> using namespace std; const int maxn ...
- POJ - 1330 Nearest Common Ancestors(dfs+ST在线算法|LCA倍增法)
1.输入树中的节点数N,输入树中的N-1条边.最后输入2个点,输出它们的最近公共祖先. 2.裸的最近公共祖先. 3. dfs+ST在线算法: /* LCA(POJ 1330) 在线算法 DFS+ST ...
- 【LCA倍增】POJ1330-Nearest Common Ancestors
[知识点:离线算法&在线算法] 一个离线算法,在开始时就需要知道问题的所有输入数据,而且在解决一个问题后就要立即输出结果. 一个在线算法是指它可以以序列化的方式一个个的处理输入,也就是说在开始 ...
- 【codevs2370】小机房的树 LCA 倍增
2370 小机房的树 时间限制: 1 s 空间限制: 256000 KB 题目等级 : 钻石 Diamond 题目描述 Description 小机房有棵焕狗种的树,树上有N个节点,节点标号为0 ...
- LCA倍增算法
LCA 算法是一个技巧性很强的算法. 十分感谢月老提供的模板. 这里我实现LCA是通过倍增,其实就是二进制优化. 任何一个数都可以有2的阶数实现 例如16可以由1 2 4 8组合得到 5可以由1 2 ...
- 洛谷 3379 最近公共祖先(LCA 倍增)
洛谷 3379 最近公共祖先(LCA 倍增) 题意分析 裸的板子题,但是注意这题n上限50w,我用的边表,所以要开到100w才能过,一开始re了两发,发现这个问题了. 代码总览 #include &l ...
- CodeVs.2370 小机房的树 ( LCA 倍增 最近公共祖先)
CodeVs.2370 小机房的树 ( LCA 倍增 最近公共祖先) 题意分析 小机房有棵焕狗种的树,树上有N个节点,节点标号为0到N-1,有两只虫子名叫飘狗和大吉狗,分居在两个不同的节点上.有一天, ...
- POJ.1986 Distance Queries ( LCA 倍增 )
POJ.1986 Distance Queries ( LCA 倍增 ) 题意分析 给出一个N个点,M条边的信息(u,v,w),表示树上u-v有一条边,边权为w,接下来有k个询问,每个询问为(a,b) ...
随机推荐
- Android之基于小米天气的天气源库
大概去年的这个时候,有跟大家分享简洁天气这个应用. 该应用一開始使用的是中国天气网的数据,可是,由于须要反复多次请求server获取信息才干满足我们的需求,因此.后来我偷偷的将天气源更换成" ...
- Python操作Saltstack
1.代码 # -*- coding:utf-8 -*- import urllib.request import urllib.parse import json class saltAPI(): d ...
- Docker安装Python3.5
方法一.通过 Dockerfile 构建 创建Dockerfile 首先,创建目录python,用于存放后面的相关东西. mkdir -p ~/python ~/python/myapp myapp目 ...
- jQuery对底部导航进行跳转并高亮显示
这两天弄一个mui的底部菜单,有点费时了,尝试了用vue写,纯js写,还有根据mui的写,还是有些问题和麻烦.直到看了网上的一些例子,才想明白,之前一直是一种点击触发事件才高亮的思维去做,这个虽然可以 ...
- UWP ListView 绑定 单击 选中项 颜色
refer: https://www.cnblogs.com/lonelyxmas/p/7650259.html using System; using System.Collections.Gene ...
- 20155334 《网络攻防》 Exp 8 Web基础
20155334 <网络攻防> Exp 8 Web基础 一.基础问题回答 1. 什么是表单? 表单在网页中主要负责数据采集功能,一个表单有三个基本组成部分: 部分 内容 表单标签 这里面包 ...
- Django实现websocket完成实时通讯、聊天室、在线客服等
一 什么是Websocket WebSocket是一种在单个TCP连接上进行全双工通信的协议 WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据.在WebS ...
- PowerBI开发 第一篇:设计PowerBI报表
PowerBI是微软新一代的交互式报表工具,把相关的静态数据转换为酷炫的可视化的,能够根据filter条件,对数据执行动态筛选,从不同的角度和粒度上分析数据.PowerBI主要由两部分组成:Power ...
- ASP.NET Core分布式项目实战-目录
前言 今年是2018年,发现已经有4年没有写博客了,在这4年的时光里,接触了很多的.NET技术,自己的技术也得到很大的进步.在这段时光里面很感谢张队长以及其他开发者一直对.NET Core开源社区做出 ...
- WayOS计费对接(零点计费系统)详细教程
零点计费系统开发也有两年了,一直都是自己和朋友在使用,今年开始有对外免费开发体验的想法,在此简单介绍一下wayos和零点计费的对接教程. 可到官网www.feidian8.com里面的首页点击查看零点 ...