Nearest Common Ancestors POJ - 1330

Nearest Common Ancestors

POJ - 1330

题意:找两个点公共祖先,裸题。

 1 #include <cstdio>
 2 #include <cstring>
 3 const int maxn=10010;
 4
 5 int f[maxn],vis[maxn];
 6
 7 int main(){
 8     int n,t;
 9    // freopen("in.txt","r",stdin);
10     scanf("%d",&t);
11     while(t--){
12         scanf("%d",&n);
13         int u,v;
14         memset(vis,0,sizeof(vis));
15         memset(f,0,sizeof(f));
16         for(int i=1;i<n;i++){
17             scanf("%d%d",&u,&v);
18             f[v]=u;
19         }
20         scanf("%d%d",&u,&v);
21         int x=u;
22         while(x){
23             vis[x]=1;
24             x=f[x];
25         }
26         x=v;
27         while(x&&!vis[x]){
28             x=f[x];
29         }
30         printf("%d\n",x);
31     }
32 }

倍增法

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 using namespace std;
 5
 6 const int maxn=10010;
 7
 8 int tot;
 9 int fr[maxn],dep[maxn<<1],p[maxn<<1];
10 int dp[maxn<<1][30],deg[maxn];
11 struct Edge{
12     int v,nex;
13 }e[maxn<<1];
14 int head[maxn];
15 int cnt=0;
16 void init(){
17     tot=0;
18     memset(head,-1,sizeof(head));
19     memset(deg,0,sizeof(deg));
20     cnt=0;
21 }
22 void add(int u,int v){
23     e[cnt].v=v;
24     e[cnt].nex=head[u];
25     head[u]=cnt++;
26 }
27
28 void dfs(int u,int f,int d){
29     tot++;
30     p[tot]=u;
31     dep[tot]=d;
32     fr[u]=tot;
33     for(int i=head[u];~i;i=e[i].nex){
34         int v=e[i].v;
35         if(v==f) continue;
36         dfs(v,u,d+1);
37         tot++;
38         p[tot]=u;
39         dep[tot]=d;
40     }
41     return ;
42 }
43
44 void RMQ_init(int n){
45     int k=1;
46     while((1<<k+1)<n) k++;
47     for(int i=1;i<=n;i++) dp[i][0]=i;
48     for(int j=1;j<=k;j++){
49         for(int i=1;i+(1<<j)-1<=n;i++){
50             int a=dp[i][j-1];
51             int b=dp[i+(1<<j-1)][j-1];
52             if(dep[a]<dep[b]) dp[i][j]=a;
53             else dp[i][j]=b;
54         }
55     }
56     return ;
57 }
58
59 int rmq(int u,int v){
60     int k=1;
61     while((1<<k+1)<v-u+1) k++;
62     int a=dp[u][k];
63     int b=dp[v-(1<<k)+1][k];
64     if(dep[a]<dep[b]) return a;
65     else return b;
66 }
67
68 int lca(int u,int v){
69     u=fr[u];
70     v=fr[v];
71     if(u>v) swap(u,v);
72     int rt=rmq(u,v);
73     return p[rt];
74 }
75
76 int main(){
77     int n,t;
78    // freopen("in.txt","r",stdin);
79     scanf("%d",&t);
80     while(t--){
81         init();
82         scanf("%d",&n);
83         int u,v;
84         for(int i=1;i<n;i++){
85             scanf("%d%d",&u,&v);
86             add(u,v);
87             deg[v]++;
88         }
89         for(int i=1;i<=n;i++) if(!deg[i]) dfs(i,-1,1);
90         RMQ_init(tot);
91         scanf("%d%d",&u,&v);
92         printf("%d\n",lca(u,v));
93     }
94     return 0;
95 }

时间: 2024-08-02 20:12:39

Nearest Common Ancestors POJ - 1330的相关文章

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

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

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 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 (朴素方法)

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

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

poj 1330 Nearest Common Ancestors lca 在线rmq

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,...,16}. Node 8 is the root of the tree.