POJ 1330 Nearest Common Ancestors 倍增算法的LCA

来源:互联网 发布:大智慧编程函数大全 编辑:程序博客网 时间:2024/06/10 08:35
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 }

 

0 0
原创粉丝点击