POJ 1330 Nearest Common Ancestors 倍增算法的LCA
POJ 1330 Nearest Common Ancestors
题意:最近公共祖先的裸题
思路:LCA和ST我们已经很熟悉了,但是这里的f[i][j]却有相似却又不同的含义。f[i][j]表示i节点的第2j个父亲是多少
这个代码不是我的,转自 邝斌博客
1 /* *********************************************** 2 Author :kuangbin 3 Created Time :2013-9-5 9:45:17 4 File Name :F:\2013ACM练习\专题学习\LCA\POJ1330_3.cpp 5 ************************************************ */ 6 7 #include <stdio.h> 8 #include <string.h> 9 #include <iostream> 10 #include <algorithm> 11 #include <vector> 12 #include <queue> 13 #include <set> 14 #include <map> 15 #include <string> 16 #include <math.h> 17 #include <stdlib.h> 18 #include <time.h> 19 using namespace std; 20 /* 21 * POJ 1330 22 * LCA 在线算法 23 */ 24 const int MAXN = 10010; 25 const int DEG = 20; 26 27 struct Edge 28 { 29 int to, next; 30 }edge[MAXN * 2]; 31 int head[MAXN], tot; 32 void addedge(int u, int v) 33 { 34 edge[tot].to = v; 35 edge[tot].next = head[u]; 36 head[u] = tot++; 37 } 38 void init() 39 { 40 tot = 0; 41 memset(head, -1, sizeof(head)); 42 } 43 int fa[MAXN][DEG];//fa[i][j]表示结点i的第2^j个祖先 44 int deg[MAXN];//深度数组 45 46 void BFS(int root) 47 { 48 queue<int>que; 49 deg[root] = 0; 50 fa[root][0] = root; 51 que.push(root); 52 while (!que.empty()) 53 { 54 int tmp = que.front(); 55 que.pop(); 56 for (int i = 1; i < DEG; i++) 57 fa[tmp][i] = fa[fa[tmp][i - 1]][i - 1]; 58 for (int i = head[tmp]; i != -1; i = edge[i].next) 59 { 60 int v = edge[i].to; 61 if (v == fa[tmp][0])continue; 62 deg[v] = deg[tmp] + 1; 63 fa[v][0] = tmp; 64 que.push(v); 65 } 66 67 } 68 } 69 int LCA(int u, int v) 70 { 71 if (deg[u] > deg[v])swap(u, v); 72 int hu = deg[u], hv = deg[v]; 73 int tu = u, tv = v; 74 for (int det = hv - hu, i = 0; det; det >>= 1, i++) 75 if (det & 1) 76 tv = fa[tv][i]; 77 if (tu == tv)return tu; 78 for (int i = DEG - 1; i >= 0; i--) 79 { 80 if (fa[tu][i] == fa[tv][i]) 81 continue; 82 tu = fa[tu][i]; 83 tv = fa[tv][i]; 84 } 85 return fa[tu][0]; 86 } 87 bool flag[MAXN]; 88 int main() 89 { 90 freopen("in.txt","r",stdin); 91 //freopen("out.txt","w",stdout); 92 int T; 93 int n; 94 int u, v; 95 scanf("%d", &T); 96 while (T--) 97 { 98 scanf("%d", &n); 99 init(); 100 memset(flag, false, sizeof(flag)); 101 for (int i = 1; i < n; i++) 102 { 103 scanf("%d%d", &u, &v); 104 addedge(u, v); 105 addedge(v, u); 106 flag[v] = true; 107 } 108 int root; 109 for (int i = 1; i <= n; i++) 110 if (!flag[i]) 111 { 112 root = i; 113 break; 114 } 115 BFS(root); 116 scanf("%d%d", &u, &v); 117 printf("%d\n", LCA(u, v)); 118 } 119 return 0; 120 }