PKU Campus 2011 B A Problem about Tree lca倍增

2024-06-14 09:32

本文主要是介绍PKU Campus 2011 B A Problem about Tree lca倍增,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

B:A Problem about Tree


总时间限制: 
1000ms 
内存限制: 
65536kB
描述

Given a tree with Nvertices and N- 1 edges, you are to answer Qqueries on "which vertex isY's parent if we choose Xas the root of the entire tree?".  

输入

The first line of input is an integer T, the number of test cases.
The first line of each test case contains N(2 ≤ N ≤ 10000) and Q(1 ≤ Q ≤ 10000).
Each of the following N - 1 lines of the test case contains two integers a(1 ≤ a ≤ N) and b(1 ≤b ≤ N) indicating an edge between and b.
Each of the following Q lines of the test case contains two integers X(1 ≤ X ≤ N) and Y(1 ≤ Y≤ NY ≠ X) indicating an query.
 

输出

For each query, output the Y's parent if X is the root of tree.

样例输入
1
5 3
1 2
1 3
4 3
3 5
2 3
4 1
5 2
样例输出
1
3
1




题意:n个节点的一棵树,m次询问:求以x为根y的父亲节点。

思路:lca倍增算法。利用bfs求出每个节点的深度以及2^i倍祖先。接下来求x和y的lca,如果lca!=y,那么y的父节点就是ancestor[y][0],不然求x的depth[x]-depth[y]-1祖先结点。画图还是比较看粗来的,详见程序:

#include<cstdio>
#include<cstring>
#include<queue>
#include<cmath>
#include<algorithm>
using namespace std;
const int MAXN=10000+100;
int n,m,edge_cnt;
int head[MAXN],ancestor[MAXN][15],depth[MAXN];
struct Edge
{int v;int next;
}edge[2*MAXN];
void init()
{edge_cnt=0;memset(head,-1,sizeof(head));
}
void addedge(int u,int v)
{edge[edge_cnt].v=v;edge[edge_cnt].next=head[u];head[u]=edge_cnt++;
}
void bfs(int root)
{queue<int>Q;ancestor[root][0]=root; depth[root]=0;Q.push(root);while(!Q.empty()){int u=Q.front(); Q.pop();for(int i=1;i<15;i++)ancestor[u][i]=ancestor[ancestor[u][i-1]][i-1];for(int i=head[u];i!=-1;i=edge[i].next){int v=edge[i].v;if(v==ancestor[u][0])continue;depth[v]=depth[u]+1; ancestor[v][0]=u;Q.push(v);}}
}
int lca(int x,int y)
{if(depth[x]<depth[y]) swap(x,y);for(int i=0;i<15;i++)if((depth[x]-depth[y])&(1<<i)) x=ancestor[x][i];if(x==y)return x;for(int i=14;i>=0;i--)if(ancestor[x][i]!=ancestor[y][i])x=ancestor[x][i],y=ancestor[y][i];return ancestor[x][0];
}
int main()
{//freopen("text.txt","r",stdin);int T;scanf("%d",&T);while(T--){scanf("%d%d",&n,&m);init();for(int i=1;i<n;i++){int u,v;scanf("%d%d",&u,&v);addedge(u,v); addedge(v,u);}bfs(1);while(m--){int x,y;scanf("%d%d",&x,&y);int fa=lca(x,y);if(fa==y){int D=depth[x]-depth[y]-1;while(D){int k=(int)(log10(1.0*D)/log10(2.0));x=ancestor[x][k];D-=(1<<k);}printf("%d\n",x);}elseprintf("%d\n",ancestor[y][0]);}}return 0;
}


这篇关于PKU Campus 2011 B A Problem about Tree lca倍增的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1060027

相关文章

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

poj1330(LCA最近公共祖先)

题意:求最近公共祖先 思路:之前学习了树链剖分,然后我就用树链剖分的一小部分知识就可以解这个题目了,记录每个结点的fa和depth。然后查找时,每次将depth大的结点往上走直到x = y。 代码如下: #include<iostream>#include<algorithm>#include<stdio.h>#include<math.h>#include<cstring>

uva 10025 The ? 1 ? 2 ? ... ? n = k problem(数学)

题意是    ?  1  ?  2  ?  ...  ?  n = k 式子中给k,? 处可以填 + 也可以填 - ,问最小满足条件的n。 e.g k = 12  - 1 + 2 + 3 + 4 + 5 + 6 - 7 = 12 with n = 7。 先给证明,令 S(n) = 1 + 2 + 3 + 4 + 5 + .... + n 暴搜n,搜出当 S(n) >=

树(Tree)——《啊哈!算法》

树 什么是树?树是一种特殊的图,不包含回路的连通无向树。 正因为树有着“不包含回路”这个特点,所以树就被赋予了很多特性。 一棵树中的任意两个结点有且仅有唯一的一条路径连通。一棵树如果有n个结点,那么它一定恰好有n-1条边。在一棵树中加一条边将会构成一个回路。 一棵树有且只有一个根结点。 没有父结点的结点称为根结点(祖先)。没有子结点的结点称为叶结点。如果一个结点既不是根结点也不是叶

226 Invert Binary Tree

//226 Invert Binary Tree//算法思路:主要使用递归算法public class Solution {public TreeNode invertTree(TreeNode root) {//1 出口 空节点if (root==null)return null;//2 递归 调用自己TreeNode left = root.left;TreeNode right = ro

11991 - Easy Problem from Rujia Liu?

题意: 输入一串整型数列,再输入两个数k,v,输出第k个v的序号。不存在则输出0,如第一个样例 8 41 3 2 2 4 3 2 11 3 //第1个3,序号为2,输出22 4 //第2个4,不存在,输出03 2 //第3个2,序号为7,输出74 2 思路: struct num {

如何限制与管控员工上网行为?四个方法让员工效率倍增!【企业员工上网行为管理】

在信息化时代,员工的上网行为直接影响着工作效率和企业的安全性。不当的网络使用,如浏览与工作无关的网站、下载不安全的文件,可能导致工作效率低下,甚至引发安全风险。因此,许多企业正在积极寻找有效的措施来管控员工的上网行为,以确保工作效率的提升。 以下是四个常见且有效的员工上网行为管理方法,帮助企业实现更高效的网络管理。 方法一:配置网络防火墙进行访问限制 最基础的员工上网行为管理方法是通过配置防

HDU 1016 Prime Ring Problem (深搜)

OJ题目 : click here ~~ 大概题意:n个数,形成一个环,使得相邻两个数的和为素数。以1开始,按字典序输出序列。 很简单的深搜。 AC_CODE int n;int visit[22];int num[22];int len;bool Is_prime(int x){for(int i = 2;i*i <= x;i++)if(x%i == 0) return

Sorry!Hbase的LSM Tree就是可以为所欲为!

我们先抛出一个问题: LSM树是HBase里使用的非常有创意的一种数据结构。在有代表性的关系型数据库如MySQL、SQL Server、Oracle中,数据存储与索引的基本结构就是我们耳熟能详的B树和B+树。而在一些主流的NoSQL数据库如HBase、Cassandra、LevelDB、RocksDB中,则是使用日志结构合并树(Log-structured Merge Tree,LSM Tr

【spring】does not have member field ‘com.sun.tools.javac.tree.JCTree qualid

spring-in-action-6-samples 的JDK版本 最小是11,我使用 了22: jdk21 jdk22 都与lombok 不兼容,必须使用兼容版本, 否则报错: thingsboard 的大神解释了: java: java.lang.NoSuchFieldError: Class com