POJ 1330 Nearest Common Ancestors 倍增算法的LCA
2015-09-22 22:01
302 查看
POJ 1330 Nearest Common Ancestors
题意:最近公共祖先的裸题
思路:LCA和ST我们已经很熟悉了,但是这里的f[i][j]却有相似却又不同的含义。f[i][j]表示i节点的第2j个父亲是多少
这个代码不是我的,转自 邝斌博客
题意:最近公共祖先的裸题
思路:LCA和ST我们已经很熟悉了,但是这里的f[i][j]却有相似却又不同的含义。f[i][j]表示i节点的第2j个父亲是多少
这个代码不是我的,转自 邝斌博客
/* *********************************************** Author :kuangbin Created Time :2013-9-5 9:45:17 File Name :F:\2013ACM练习\专题学习\LCA\POJ1330_3.cpp ************************************************ */ #include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> #include <vector> #include <queue> #include <set> #include <map> #include <string> #include <math.h> #include <stdlib.h> #include <time.h> using namespace std; /* * POJ 1330 * LCA 在线算法 */ const int MAXN = 10010; const int DEG = 20; struct Edge { int to, next; }edge[MAXN * 2]; int head[MAXN], tot; void addedge(int u, int v) { edge[tot].to = v; edge[tot].next = head[u]; head[u] = tot++; } void init() { tot = 0; memset(head, -1, sizeof(head)); } int fa[MAXN][DEG];//fa[i][j]表示结点i的第2^j个祖先 int deg[MAXN];//深度数组 void BFS(int root) { queue<int>que; deg[root] = 0; fa[root][0] = root; que.push(root); while (!que.empty()) { int tmp = que.front(); que.pop(); for (int i = 1; i < DEG; i++) fa[tmp][i] = fa[fa[tmp][i - 1]][i - 1]; for (int i = head[tmp]; i != -1; i = edge[i].next) { int v = edge[i].to; if (v == fa[tmp][0])continue; deg[v] = deg[tmp] + 1; fa[v][0] = tmp; que.push(v); } } } int LCA(int u, int v) { if (deg[u] > deg[v])swap(u, v); int hu = deg[u], hv = deg[v]; int tu = u, tv = v; for (int det = hv - hu, i = 0; det; det >>= 1, i++) if (det & 1) tv = fa[tv][i]; if (tu == tv)return tu; for (int i = DEG - 1; i >= 0; i--) { if (fa[tu][i] == fa[tv][i]) continue; tu = fa[tu][i]; tv = fa[tv][i]; } return fa[tu][0]; } bool flag[MAXN]; int main() { freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); int T; int n; int u, v; scanf("%d", &T); while (T--) { scanf("%d", &n); init(); memset(flag, false, sizeof(flag)); for (int i = 1; i < n; i++) { scanf("%d%d", &u, &v); addedge(u, v); addedge(v, u); flag[v] = true; } int root; for (int i = 1; i <= n; i++) if (!flag[i]) { root = i; break; } BFS(root); scanf("%d%d", &u, &v); printf("%d\n", LCA(u, v)); } return 0; }
相关文章推荐
- HDU2504:又见GCD
- Javascript高级程序设计第17章(错误处理与调试)
- HDU 5119 Happy Matt Friends(dp+位运算)
- hdu acm 2576
- 静态成员的使用
- Android_开发人员经常使用的颜色
- 基础DFS-Lake Counting
- 基础DFS-Lake Counting
- 图像处理中的数学原理详解(Part2)
- ocp-v13-480
- CYC-多线程 售票问题
- 用C语言编写的简单的猜数字游戏
- spark sql cache
- spark sql cache
- spark sql cache
- ubuntu中孤儿进程的父进程pid并不是1??
- spark sql cache
- hdu1573 X问题(中国剩余定理)
- 数独游戏的设计与实现之第一篇——理解数独过程
- hdu3078 伪LCA……