HDU 6031 Innumerable Ancestors (LCA)
来源:互联网 发布:mysql重置root密码 编辑:程序博客网 时间:2024/05/17 01:35
There is a tree having n nodes, labeled from 1 to n. The root of the tree is always 1, and the depth of a node p is the number of nodes on the shortest path between node p and the root.
In computer science, the Lowest Common Ancestor (LCA) of two nodes v and w in a tree is the lowest (i.e. deepest) node that has both v and w as descendants, where we define each node to be a descendant of itself (so if v has a direct connection from w, w is the lowest common ancestor).
You have to answer m queries. Each query gives two non-empty node sets A and B, there might be some nodes in both sets.
You should select one node x from set A, and one node y from set B, x and y can be the same node. Your goal is to maximize the depth of the LCA of x and y.
Please write a program to answer these queries.
题意
给定 N 节点的树,问集合 A 中节点 x 与集合 B 中节点 y 的 LCA(x, y) 的深度的最大值。
解题思路
根据 DFS 序,若两个点的 DFS 序越接近,则两个点的 LCA 的深度越大。
故可将集合 A 与集合 B 中的点分别按照 DFS 序排序。遍历集合 A 中所有元素,对任意一个元素 x,在集合 B 中二分查找与其 DFS 序最接近的点
代码
#include<bits/stdc++.h>using namespace std;const int N = 100000 + 10;const int maxh = 20; //log2(N);struct Edge { int to, nxt;} e[N*2];int head[N], cnt;void addedge(int u, int v) { e[++cnt].nxt = head[u]; e[cnt].to = v; head[u] = cnt;}int id[N], idx, a[N], b[N], n, m;void genId(int rt, int pre) { id[rt] = ++idx; for(int i=head[rt];i;i=e[i].nxt) { if(e[i].to == pre) continue; genId(e[i].to, rt); }}bool cmp(int a, int b) { return id[a] < id[b];}int dep[N], anc[N][20];void dfs(int rt) { static int Stack[N]; int top = 0; dep[rt] = 1; for(int i=0;i<maxh;i++) anc[rt][i] = rt; Stack[++top] = rt; while(top) { int x = Stack[top]; if(x != rt) { for(int i=1, y;i<maxh;i++) y = anc[x][i-1], anc[x][i] = anc[y][i-1]; } for(int &i=head[x];i;i=e[i].nxt) { int y = e[i].to; if(y != anc[x][0]) { dep[y] = dep[x] + 1; anc[y][0] = x; Stack[++top] = y; } } while(top && head[Stack[top]] == 0) top--; }}void swim(int &x, int H) { for(int i=0;H;i++) { if(H & 1) x = anc[x][i]; H /= 2; }}int lca(int x, int y) { int i; if(dep[x] > dep[y]) swap(x, y); swim(y, dep[y]-dep[x]); if(x == y) return x; for(;;) { for(i=0;anc[x][i] != anc[y][i];i++); if(i == 0) return anc[x][0]; x = anc[x][i-1]; y = anc[y][i-1]; } return -1;}void init() { memset(head, 0, sizeof(head)); cnt = 0; idx = 0;}int main(){ while(scanf("%d %d", &n, &m)!=EOF) { init(); for(int i=1, u, v;i<n;i++) scanf("%d %d",&u,&v), addedge(u, v), addedge(v, u); genId(1, -1); dfs(1); for(int i=1, ka, kb;i<=m;i++) { scanf("%d",&ka); for(int j=0;j<ka;j++) scanf("%d",&a[j]); sort(a, a+ka, cmp); scanf("%d",&kb); for(int j=0;j<kb;j++) scanf("%d",&b[j]); sort(b, b+kb, cmp); int ans = 0; for(int j=0, pos;j<ka;j++) { pos = lower_bound(b, b+kb, a[j], cmp) - b; if(pos < kb) ans = max(ans, dep[lca(a[j], b[pos])]); if(--pos >= 0) ans = max(ans, dep[lca(a[j], b[pos])]); } printf("%d\n", ans); } }}
- HDU 6031 Innumerable Ancestors (LCA)
- hdu 6031 Innumerable Ancestors(LCA+二分)
- HDU 6031 Innumerable Ancestors【LCA】
- HDU 6031 Innumerable Ancestors(LCA,树链剖分)
- hdu 6031 Innumerable Ancestors lca + 二分
- hdu 6031 Innumerable Ancestors
- HDU 6031 Innumerable Ancestors[树链剖分]
- 【HDU6031】Innumerable Ancestors(二分+LCA)
- 2017CCPC女生赛 hdu 6031 Innumerable Ancestors
- hdu6031 Innumerable Ancestors
- HDU6031 Innumerable Ancestors 倍增
- Closest Common Ancestors(LCA)
- poj1470Closest Common Ancestors(lca)
- [PKU 1330]Nearest Common Ancestors(LCA)
- poj Nearest Common Ancestors(LCA+Tarjan)
- (简单LCA) Nearest Common Ancestors(P1330)
- ZOJ 1141 Closest Common Ancestors(LCA)
- poj 1330 Nearest Common Ancestors(LCA)
- [Leetcode] 141. Linked List Cycle 解题报告
- 关于去掉tableViewCell 多余分割线
- elasticsearch rest api操作
- Nginx隐藏软件版本号信息
- 同一服务器中多开 tomcat
- HDU 6031 Innumerable Ancestors (LCA)
- Android 中处理POWER/HOME流程
- JS事件--事件处理程序之HTML事件处理程序
- 目标跟踪方法的发展概述
- 查准率、查全率
- ionic-底部分享功能
- nexus3.3.1上传第三方jar包
- js省市县封装
- 搭建Windows Embedded Compact 7开发环境