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 }
时间: 2024-10-25 16:27:35

POJ 1330 Nearest Common Ancestors 倍增算法的LCA的相关文章

POJ 1330 Nearest Common Ancestors (最近公共祖先LCA + 详解博客)

LCA问题的tarjan解法模板 LCA问题 详细 1.二叉搜索树上找两个节点LCA 1 public int query(Node t, Node u, Node v) { 2 int left = u.value; 3 int right = v.value; 4 5 //二叉查找树内,如果左结点大于右结点,不对,交换 6 if (left > right) { 7 int temp = left; 8 left = right; 9 right = temp; 10 } 11 12 whi

POJ 1330 Nearest Common Ancestors LCA题解

本题是一个多叉树,然后求两点的最近公共单亲节点. 就是典型的LCA问题.这是一个很多解法的,而且被研究的很透彻的问题. 原始的解法:从根节点往下搜索,若果搜索到两个节点分别在一个节点的两边,那么这个点就是最近公共单亲节点了. Trajan离线算法:首次找到两个节点的时候,如果记录了他们的最低单亲节点,那么答案就是这个最低的单亲节点了. 问题是如何有效记录这个最低单亲节点,并有效根据遍历的情况更新,这就是利用Union Find(并查集)记录已经找到的节点,并及时更新最新访问的节点的当前最低单亲节

POJ 1330 Nearest Common Ancestors LCA(在线RMQ,离线Tarjan)

链接:http://poj.org/problem?id=1330 题意:只看题目就知道题目是什么意思了,最近公共祖先,求在一棵树上两个节点的最近公共祖先. 思路:求最近公共祖先有两种算法,在线和离线,在线方法是用RMQ求LCA,一句话总结就是在从DFS时,从第一个点到第二个点的最短路径中深度最浅的点就是公共祖先,用RMQ处理,一般问题的最优解决方式的复杂度是O(NlogN)的预处理+N*O(1)的查询.离线方法是Tarjan算法,将所有询问的两个点都记录下来,在DFS过程中不断将每个点自身作为

POJ 1330 Nearest Common Ancestors(树)

Nearest Common Ancestors Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 17628   Accepted: 9335 Description A rooted tree is a well-known data structure in computer science and engineering. An example is shown below: In the figure, each

[POJ 1330] Nearest Common Ancestors (朴素方法)

POJ 1330: Nearest Common Ancestors Time Limit: 1000ms Memory Limit: 32Mb Description A rooted tree is a well-known data structure in computer science and engineering. An example is shown below:  In the figure, each node is labeled with an integer fro

POJ - 1330 Nearest Common Ancestors(基础LCA)

POJ - 1330 Nearest Common Ancestors Time Limit: 1000MS   Memory Limit: 10000KB   64bit IO Format: %lld & %llu Submit Status Description A rooted tree is a well-known data structure in computer science and engineering. An example is shown below:  In t

poj 1330 Nearest Common Ancestors

题目连接 http://poj.org/problem?id=1330 Nearest Common Ancestors Description A rooted tree is a well-known data structure in computer science and engineering. An example is shown below:  In the figure, each node is labeled with an integer from {1, 2,...,

POJ 1330 Nearest Common Ancestors 【最近公共祖先LCA算法+Tarjan离线算法】

Nearest Common Ancestors Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 20715   Accepted: 10910 Description A rooted tree is a well-known data structure in computer science and engineering. An example is shown below: In the figure, each

[最近公共祖先] POJ 1330 Nearest Common Ancestors

Nearest Common Ancestors Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 27316   Accepted: 14052 Description A rooted tree is a well-known data structure in computer science and engineering. An example is shown below:  In the figure, eac