PKU Campus 2011 B A Problem about Tree lca倍增
来源:互联网 发布:javascript 禁止跳转 编辑:程序博客网 时间:2024/04/20 21:59
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 a and b.
Each of the following Q lines of the test case contains two integers X(1 ≤ X ≤ N) and Y(1 ≤ Y≤ N, Y ≠ X) indicating an query.
- 输出
For each query, output the Y's parent if X is the root of tree.
- 样例输入
15 31 21 34 33 52 34 15 2
- 样例输出
131
题意: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); } else printf("%d\n",ancestor[y][0]); } } return 0;}
- PKU Campus 2011 B A Problem about Tree lca倍增
- PJOI PKU Campus 2011 B:A Problem about Tree LCA 求任意点x为根的y的父节点
- PKU 1020 A Problem about Tree LCA
- BZOJ 2588 Count on a tree 主席树+倍增LCA
- SPOJ QTREE2 Query on a tree II (倍增LCA)
- SPOJ Query on a tree II (倍增LCA)
- SPOJ Query on a tree II (倍增LCA)
- SPOJ QTREE2 Query on a tree II 倍增lca
- FOJ 1000 PKU 1000 FJNU 1000 A+B Problem
- 2588: Spoj 10628. Count on a tree[可持久化线段树+倍增lca]
- SPOJ 913 QTREE系列- Query on a tree II (倍增LCA)
- 洛谷 P2633 Count on a tree[bzoj2588](倍增lca+主席树)
- 在线LCA 倍增法 Codeforces Round #294 (Div. 2) E - A and B and Lecture Rooms
- Codeforces Round #294 (Div. 2) E. A and B and Lecture Rooms(倍增LCA+树形DP)
- Codeforces Round #294 (Div. 2)-E. A and B and Lecture Rooms(LCA倍增)
- 【弱校胡策】 DQS 的 tree|倍增LCA
- PKU Campus 2014 B:An Easy Task(模拟)
- A problem about printf
- C++ 学习笔记
- 俄罗斯方块(一) 界面设计与实现
- google内购In-App Billing
- 为什么有些语言会比别的快?
- 基于libuv的TCP设计
- PKU Campus 2011 B A Problem about Tree lca倍增
- UVAOJ 10591 happy number
- switch中的非case非default语句会执行吗?
- Spring3.0前的架构说明
- 不同的语言和硬件创建资源
- 研发团队平稳度过“从小到大”并非易事
- 异形卵
- samba的安装(tar.gz方式) (转载)
- 将各类wsdl转成java调用