HDU 6031 Innumerable Ancestors【LCA】
来源:互联网 发布:如何管理网络客服 编辑:程序博客网 时间:2024/06/06 08:41
题目链接
题意:n个点形成的一棵树,根节点为1,给两个点的集合A和B,从A和B中各取出一点,要求这两个点的LCA最大(深),输出最大深度。
先求一遍LCA,因为两个点的LCA不可能比这两个点都要深,所以按深度从大到小排序,剪枝:如果当前的最大深度比比较到的点要深则直接退出。
倍增LCA
#include <iostream>#include <cstring>#include <cstdio>#include <cmath>#include <algorithm>#include <map>using namespace std;const int maxn = 100000 + 10;int e;int n;int deep[maxn];int p[maxn][20];int head[maxn];int num1[maxn];int num2[maxn];struct Edge{ int v, next;} edge[maxn * 2];void addedge(int x, int y){ edge[e].v = y; edge[e].next = head[x]; head[x] = e ++;}void Init(){ memset(head, -1, sizeof(head)); memset(p, -1, sizeof(p)); e = 0;}void init(){ int i, j; //p[i][j]表示i结点的第2^j祖先 for (j = 1; (1 << j) <= n; j++) for (i = 1; i <= n; i++) if (p[i][j - 1] != -1) p[i][j] = p[p[i][j - 1]][j - 1]; //i的第2^j祖先就是i的第2^(j-1)祖先的第2^(j-1)祖先}int lca(int a, int b) { int i, j; if (deep[a] < deep[b]) swap(a, b); for ( i = 0; (1 << i) <= deep[a]; i++ ); i--; for ( j = i; j >= 0; j-- ) { if (deep[a] - (1 << j) >= deep[b]) { a = p[a][j]; } } if (a == b) return a; for (j = i; j >= 0; j--) { if (p[a][j] != -1 && p[a][j] != p[b][j]) { a = p[a][j]; b = p[b][j]; } } return p[a][0];}void dfs(int u, int fa, int d){ deep[u] = d; for (int i = head[u]; i != -1; i = edge[i].next) { int to = edge[i].v; if (fa != to) { p[to][0] = u; //p[x][0]保存x的父节点为u; dfs(to, u, d + 1); } }}bool cmp(int x, int y){ return deep[x] > deep[y];}int main(){ int m; while (~scanf("%d %d", &n , &m)) { int a, b; Init(); for (int i = 0; i < n - 1; i ++) { scanf("%d%d", &a, &b); addedge(a, b); addedge(b, a); } deep[1] = 1; dfs(1, 1, 1); init(); int k1, k2; while (m --) { int max1 = 0; scanf("%d", &k1); for (int i = 0; i < k1; i ++) scanf("%d", &num1[i]); scanf("%d", &k2); for (int i = 0; i < k2; i ++) scanf("%d", &num2[i]); sort(num1, num1 + k1, cmp); sort(num2, num2 + k2, cmp); for (int i = 0 ; i < k1; i ++) { if (max1 >= deep[num1[i]]) break; for (int j = 0; j < k2; j ++) max1 = max(max1, deep[lca(num1[i], num2[j])]); } printf("%d\n", max1); } } return 0;}
阅读全文
0 0
- 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 倍增
- hdu1470Closest Common Ancestors LCA
- Nearest Common Ancestors--LCA
- 1330 Nearest Common Ancestors //LCA
- 1470 Closest Common Ancestors //LCA
- poj1330Nearest Common Ancestors(LCA小结)
- POJ1470 Closest Common Ancestors LCA
- poj1470-Closest Common Ancestors(LCA)
- LeetCode 198. House Robber
- 【JqGrid】JqGrid关于loadonce:true后trigger("reloadGrid")无效,loadonce:false后无法翻页的问题
- Android适配疑难问题(dp,px,sp,icon图标)
- xgboost原理
- FFMPEG结构体分析:AVIOContext
- HDU 6031 Innumerable Ancestors【LCA】
- 比较好的取色工具汇总
- activemq 添加生产者消费者连接密码
- 利用Breadth-First Search (BFS)算法寻找图中的最短路径和所有路径
- 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数
- Android异常之fragment添加ViewPager
- Android应用层制作LED指示灯
- 统计cpu相关信息
- UVA489解题报告(刽子手游戏)