LCA SP913 QTREE2 - Query on a tree II
SP913 QTREE2 - Query on a tree II
给定一棵n个点的树,边具有边权。要求作以下操作:
DIST a b 询问点a至点b路径上的边权之和
KTH a b k 询问点a至点b有向路径上的第k个点的编号
有多组测试数据,每组数据以DONE结尾。
裸的LCA。
在处理第二个操作时,我直接向上数跳了多少个。
顾z大佬说不能这么做,要求出跳到那个点的深度再去跳。
真的是这样,不过懒得想了,应该是+1-1的误差。 balabala。。。
code:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int wx=50017;
int dep[wx],dis[wx];
int f[wx][23];
int head[wx];
int num,n,t;
char opt[7];
inline int read(){
int sum=0,f=1; char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
while(ch>='0'&&ch<='9'){sum=(sum<<1)+(sum<<3)+ch-'0'; ch=getchar();}
return sum*f;
}
struct e{
int nxt,to,dis;
}edge[wx*2];
void add(int from,int to,int dis){
edge[++num].nxt=head[from];
edge[num].to=to;
edge[num].dis=dis;
head[from]=num;
}
void dfs(int u,int fa){
dep[u]=dep[fa]+1;
for(int i=head[u];i;i=edge[i].nxt){
int v=edge[i].to;
if(v==fa)continue;
f[v][0]=u;dis[v]=dis[u]+edge[i].dis;
dfs(v,u);
}
}
void pre(){
for(int j=1;j<=21;j++)for(int i=1;i<=n;i++)f[i][j]=f[f[i][j-1]][j-1];
}
int LCA(int x,int y){
if(dep[x]<dep[y])swap(x,y);
for(int i=21;i>=0;i--){
if(dep[f[x][i]]>=dep[y]){
x=f[x][i];
}
}
if(x==y)return x;
for(int i=21;i>=0;i--){
if(f[x][i]!=f[y][i]){
x=f[x][i]; y=f[y][i];
}
}
return f[x][0];
}
int find(int x,int k){
for(int i=21;i>=0;i--){
if(dep[f[x][i]]>=k)x=f[x][i];
}
return x;
}
int main(){
t=read();
while(t--){
n=read();
memset(head,0,sizeof head); num=1;
memset(edge,0,sizeof edge);
for(int i=1;i<n;i++){
int x,y,z;
x=read(); y=read(); z=read();
add(x,y,z); add(y,x,z);
}
dfs(1,0); pre();
while(1){
scanf("%s",opt+1);
if(opt[2]=='O')break;
if(opt[2]=='I'){
int x,y;
x=read(); y=read();
int lca=LCA(x,y);
printf("%d\n",dis[x]+dis[y]-2*dis[lca]);
}
if(opt[1]=='K'){
int a,b,k;
a=read(); b=read(); k=read();
int lca=LCA(a,b);
if(dep[a]-dep[lca]+1>=k)printf("%d\n",find(a,dep[a]-k+1));
else printf("%d\n",find(b,k-dep[a]+2*dep[lca]-1));
}
}
}
}
LCA SP913 QTREE2 - Query on a tree II的更多相关文章
- SP913 QTREE2 - Query on a tree II
思路 第一个可以倍增,第二个讨论在a到lca的路径上还是lca到b的路径上, 倍增即可 代码 #include <cstdio> #include <algorithm> #i ...
- 【SPOJ QTREE2】QTREE2 - Query on a tree II(LCA)
You are given a tree (an undirected acyclic connected graph) with N nodes, and edges numbered 1, 2, ...
- [SPOJ913]QTREE2 - Query on a tree II【倍增LCA】
题目描述 [传送门] 题目大意 给一棵树,有两种操作: 求(u,v)路径的距离. 求以u为起点,v为终点的第k的节点. 分析 比较简单的倍增LCA模板题. 首先对于第一问,我们只需要预处理出根节点到各 ...
- SPOJ QTREE2 Query on a tree II
传送门 倍增水题…… 本来还想用LCT做的……然后发现根本不需要 //minamoto #include<bits/stdc++.h> using namespace std; #defi ...
- spoj 913 Query on a tree II (倍增lca)
Query on a tree II You are given a tree (an undirected acyclic connected graph) with N nodes, and ed ...
- LCA【SP913】Qtree - Query on a tree II
Description 给定一棵n个点的树,边具有边权.要求作以下操作: DIST a b 询问点a至点b路径上的边权之和 KTH a b k 询问点a至点b有向路径上的第k个点的编号 有多组测试数据 ...
- QTREE2 spoj 913. Query on a tree II 经典的倍增思想
QTREE2 经典的倍增思想 题目: 给出一棵树,求: 1.两点之间距离. 2.从节点x到节点y最短路径上第k个节点的编号. 分析: 第一问的话,随便以一个节点为根,求得其他节点到根的距离,然后对于每 ...
- Query on a tree II 倍增LCA
You are given a tree (an undirected acyclic connected graph) with N nodes, and edges numbered 1, 2, ...
- SPOJ Query on a tree II (树剖||倍增LCA)(占位)
You are given a tree (an undirected acyclic connected graph) with N nodes, and edges numbered 1, 2, ...
随机推荐
- altium designer 中器件原理图库中,将一个器件分成几部分是如何操作的?就是如何用part表示?
在SCH Library的Components中选中你要添加part的器件,tools菜单--new part即可
- 10-12C#基础--运算符
10-12C#基础--运算符 课前作业:班级内人数的姓名和年龄,分别写出之后并汇总. 一.运算符的分类 1.数学运算符(7个) 1)+(加号) 例: 2)-(减号) 例: 3)*(乘号) 例: 4)/ ...
- windows 修改端口数据及连接时间
最近线上遇到windows机器访问其他机器的时候失败的情况.实际就是本地的端口不够用造成的. D:\>netsh interface ipv4 show dynamicportrange pro ...
- 最全 C 语言常用算法详解-排序-队列-堆栈-链表-递归-树 (面试有用)
具体 源代码 案例查看github,持续更新中............ github地址:https://github.com/Master-fd/C-Algorithm 1. 二分法查找 2. 冒泡 ...
- 关于JS正则表达式的一篇文章(转载)
原文:http://www.cnblogs.com/xujh/archive/2008/08/21/1273525.html <input onkeypress="return ...
- close、flush、read、readline、seek、tell、truncate、write的使用
1.close关闭文件 f1= open("ha.log","r+",encoding="utf-8") data = f1.read() ...
- transient关键字的理解
谈到这个transient这个关键字,我们应该会立马想到序列化这个过程:什么是序列化?什么又是反序列化呢?序列化就是将对象转化内成二进制,而反序列化就是就二进制文件转换成对象的过程.一旦变量使用了tr ...
- PHP处理密码的几种方式
在 PHP中,经常会对用户身份进行认证.本文意在讨论对密码的处理,也就是对密码的加密处理. 1.MD5 相信很多PHP开发者在最先接触PHP的时候,处理密码的首选加密函数可能就是MD5了,我当时就是这 ...
- ROS Learning-021 learning_tf-05(编程) now() 和 Time(0) 的区别 (Python版)
ROS Indigo learning_tf-05 now() 和 Time(0)的区别 (Python版) - waitForTransform() 函数 我使用的虚拟机软件:VMware Work ...
- DPDK内存管理(1)(转)
1 前言 DPDK将利用hugepage预留的物理内存统一的组织管理起来,然后以库的方式对外提供使用的接口.下图展示了DPDK中内存有关的模块的相互关系. rte_eal 是统一 ...